Пример #1
0
void
run_phase (phases_t phase, char *name, string_list_t *args)
{
	char **argv;
	int argc = 1;
	string_item_t *p;
	char *output = NULL;
	char *input = NULL;
	boolean save_stderr = FALSE;
	int fdin, fdout;
	int forkpid;
	int waitpid;
	int waitstatus;
	int termsig;
	int	num_maps;
	char *rld_path, *absoft_path;
	struct stat stat_buf;
	const boolean uses_message_system = 
			(phase == P_f90_fe || phase == P_f90_cpp ||
			 phase == P_cppf90_fe);

#if defined(__APPLE__)
        // pass -Wa,-W to assembler so we ignore unknowns
        int hack_as_W = 0;
        if (strcmp(name, "/usr/bin/gcc") == 0)
        {
                hack_as_W = 1;
		argc++;
        }
#endif

	if (show_flag) {
		/* echo the command */
		fprintf(stderr, "%s ", name);
		print_string_list(stderr, args);
	}
	if (!execute_flag) return;

	if (time_flag) init_time();

	/* copy arg_list to argv format that exec wants */
	for (p = args->head; p != NULL; p=p->next) {
		//bug# 581, bug #932, bug #1049
		if (p->name == NULL) 
                  continue;
		argc++;
	}

	argv = (char **) malloc((argc+1)*sizeof(char*));
	argv[0] = name;
	for (argc = 1, p = args->head; p != NULL; argc++, p=p->next) {
		//bug# 581, bug #932
		if (p->name[0] == '\0') {
		  argc--;
                  continue;
		}
		/* don't put redirection in arg list */
		if (strcmp(p->name, "<") == 0) {
			/* has input file */
			input = p->next->name;
			break;
		} else if (strcmp(p->name, ">") == 0) {
			/* has output file */
			output = p->next->name;
			break;
		} else if (strcmp(p->name, ">&") == 0) {
			/* has error output file */
			output = p->next->name;
			save_stderr = TRUE;
			break;
		}
		argv[argc] = p->name;
	}
#if defined(__APPLE__)
	if (hack_as_W)
	{
#ifndef Is_True_On
		argv[argc++] = ""; // "-Wa,-W";
#endif
	}
#endif
	argv[argc] = NULL;

	/* fork a process */
	forkpid = fork();
	if (forkpid == -1) {
		error("no more processes");
		cleanup ();
		do_exit (RC_SYSTEM_ERROR);
		/* NOTREACHED */
	}

	if (forkpid == 0) {
		char *my_path, *l_path, *l32_path, *nls_path, *env_path;
		
		/* child */
		/* if we want memory stats, we have to wait for
		   parent to connect to our /proc */
		if (input != NULL) {
			if ((fdin = open (input, O_RDONLY)) == -1) {
				error ("cannot open input file %s", input);
				cleanup ();
				do_exit (RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
	    		dup2 (fdin, fileno(stdin));
		}
		if (output != NULL) {
			if ((fdout = creat (output, 0666)) == -1) {
				error ("cannot create output file %s", output);
				cleanup ();
				do_exit (RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
			if (save_stderr) {
	    			dup2 (fdout, fileno(stderr));
			} else {
	    			dup2 (fdout, fileno(stdout));
			}
		} 

		my_path = get_binutils_lib_path();
		rld_path = get_phase_ld_library_path (phase);
		absoft_path = get_absoft_ld_library_path (phase);
		
		if (absoft_path != 0)
			asprintf(&my_path, "%s:%s", my_path, absoft_path);

		if (rld_path != 0)
			asprintf(&my_path, "%s:%s", my_path, rld_path);
		
		l_path = l32_path = my_path;
		
		if (ld_library_path)
			asprintf(&l_path, "%s:%s", my_path, ld_library_path);

		if (ld_libraryn32_path)
			asprintf(&l32_path, "%s:%s", my_path,
				 ld_libraryn32_path);

		my_putenv("LD_LIBRARY_PATH", l_path);
		my_putenv("LD_LIBRARYN32_PATH", l32_path);
		
		// Set up NLSPATH, for the Fortran front end.

		nls_path = getenv("NLSPATH");
		env_path = get_phase_dir(P_f90_fe);

		if (nls_path) {
		    my_putenv("NLSPATH", "%s:%s/%%N.cat", nls_path, env_path);
		} else {
		    my_putenv("NLSPATH", "%s/%%N.cat", env_path);
		}

		if (uses_message_system && getenv("ORIG_CMD_NAME") == NULL)
		   my_putenv("ORIG_CMD_NAME", "%s", program_name);

		if (phase == P_f90_fe) {
		   char *root;
		   char *modulepath;
		   int len;
		   char *new_env;
		   char *env_name = "FORTRAN_SYSTEM_MODULES=";
		   char *env_val = "/usr/lib/f90modules";
		   root = getenv("TOOLROOT");
		   if (root != NULL) {
		      len = strlen(env_val) + strlen(root) +3 + strlen(env_val);
		      new_env = alloca(len);
		      sprintf(new_env,"%s/%s:%s",root,env_val,env_val);
		      env_val = new_env;
		   }
		   modulepath = string_copy(getenv("FORTRAN_SYSTEM_MODULES"));
		   if (modulepath != NULL) {
		      /* Append env_val to FORTRAN_SYSTEM_MODULES */
		      if (modulepath[strlen(modulepath)-1] == ':') {
			 /* Just append env_val */
			 len = strlen(modulepath) + strlen(env_val) + 1;
			 new_env = alloca(len);
			 sprintf(new_env,"%s%s",modulepath,env_val);
		      } else {
			 /* append :env_val */
			 len = strlen(modulepath) + strlen(env_val) + 2;
			 new_env = alloca(len);
			 sprintf(new_env,"%s:%s",modulepath,env_val);
		      }
		      env_val = new_env;
		   }
		   
		   my_putenv ("FORTRAN_SYSTEM_MODULES", "%s", env_val);
		}
		/* need to setenv COMPILER_PATH for collect to find ld */
		my_putenv ("COMPILER_PATH", "%s", get_phase_dir(P_collect));

		/* Tell IPA where to find the driver. */
#if defined(ABSOFT_EXTENSIONS)
		my_putenv ("COMPILER_BIN", "%s/" PSC_NAME_PREFIX "f90",
				get_executable_dir());
#else
		my_putenv ("COMPILER_BIN", "%s/" PSC_NAME_PREFIX "cc-"
			   PSC_FULL_VERSION, get_executable_dir());
#endif

		my_execv(name, argv);
	} else {
		/* parent */
		int procid;	/* id of the /proc file */
		while ((waitpid = wait (&waitstatus)) != forkpid) {
			if (waitpid == -1) {
				error("bad return from wait");
				cleanup();
				do_exit(RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
		}
		if (time_flag) print_time(name);

		if (WIFSTOPPED(waitstatus)) {
			termsig = WSTOPSIG(waitstatus);
			error("STOPPED signal received from %s", name);
			cleanup();
			do_exit(RC_SYSTEM_ERROR);
			/* NOTREACHED */
		} else if (WIFEXITED(waitstatus)) {
		        int status = WEXITSTATUS(waitstatus);
			extern int inline_t;
			boolean internal_err = FALSE;
			boolean user_err = FALSE;
		
			if (phase == P_prof) {
                           /* Make sure the .cfb files were created before
                              changing the STATUS to OKAY */
                           if (prof_file != NULL) {
                              if (!(stat(fb_file, &stat_buf) != 0 && errno == ENOENT))
                                  status = RC_OKAY;
                           } else {
			      internal_error("No count file was specified for a prof run");
			      perror(program_name);
                           }
                        }

			if (phase == P_f90_fe && keep_listing) {
			    char *cif_file;
			    cif_file = construct_given_name(
					  drop_path(source_file), "T", TRUE);
                            if (!(stat(cif_file, &stat_buf) != 0 && errno == ENOENT))
			       f90_fe_status = status;
			       f90_fe_name = string_copy(name);

			       /* Change the status to OKAY so that we can 
				* execute the lister on the cif_file; we will
				* take appropriate action on this status once 
				* the lister has finished executing. See below.
				*/

			       status = RC_OKAY;
                        }

			if (phase == P_lister) {
			   if (status == RC_OKAY && f90_fe_status != RC_OKAY) {

			      /* We had encountered an error in the F90_fe phase
			       * but we ignored it so that we could execute the
			       * lister on the cif file; we need to switch the
			       * status to the status we received from F90_fe
			       * and use the name of the F90_fe_phase, so that
			       * we can issue a correct error message.
			       */

			       status = f90_fe_status;
			       name = string_copy(f90_fe_name);

			       /* Reset f90_fe_status to OKAY for any further
				* compilations on other source files.
				*/

			       f90_fe_status = RC_OKAY;
                           }
                        }

			switch (status) {
			case RC_OKAY:
				if (inline_t == UNDEFINED
				    && is_matching_phase(
					get_phase_mask(phase), P_any_fe) )
				{
					inline_t = FALSE;
				}
				break;
			case RC_NEED_INLINER:
				if (inline_t == UNDEFINED
				    && is_matching_phase(
					get_phase_mask(phase), P_any_fe) )
				{
					inline_t = TRUE;
				}
				/* completed successfully */
				break;
				
			case RC_USER_ERROR:
			case RC_NORECOVER_USER_ERROR:
			case RC_SYSTEM_ERROR:
			case RC_GCC_ERROR:
				user_err = TRUE;
				break;

			case RC_OVERFLOW_ERROR:
				if (!ran_twice && phase == P_be) {
					/* try recompiling with larger limits */
					ran_twice = TRUE;
					add_string (args, "-TENV:long_eh_offsets");
					add_string (args, "-TENV:large_stack");
					run_phase (phase, name, args);
					return;
				}
				internal_err = TRUE;
				break;
			case RC_INTERNAL_ERROR:
				internal_err = TRUE;
				break;
			default:
				internal_err = TRUE;
				break;
			} 
			if (internal_err) {
				if (phase == P_ld || phase == P_ldplus ||
#ifdef KEY
				    phase == P_gas ||	// bug 4846
#endif
				    phase == P_gcpp || phase == P_gcpp_plus) {
					if (phase == P_gas)
						internal_error_occurred = 1;
					log_error("%s returned non-zero status %d",
						  name, status);
					nomsg_error(status);
				} else {
					internal_error("%s returned non-zero status %d",
						       name, status);
				}
			}
			else if (user_err) {
				/* assume phase will print diagnostics */
				if (phase == P_c_gfe || phase == P_cplus_gfe) {
					nomsg_error(RC_INTERNAL_ERROR);
				}
				else if (!show_flag || save_stderr) {
					nomsg_error(RC_USER_ERROR);
				} else {
					error("%s returned non-zero status %d",
						name, status);
				}
			}
			ran_twice = FALSE;
			return;
		} else if(WIFSIGNALED(waitstatus)){
			termsig = WTERMSIG(waitstatus);
			switch (termsig) {
			case SIGHUP:
			case SIGINT:
			case SIGQUIT:
			case SIGKILL:
			case SIGTERM:
				error("%s died due to signal %d", name, termsig);
				break;
			default:
				internal_error("%s died due to signal %d",
					       name, termsig);
				break;
			}
#ifndef __CYGWIN__
			if(waitstatus & WCOREFLAG) {
				error("core dumped");
			}
#endif
			if (termsig == SIGKILL) {
				error("Probably caused by running out of swap space -- check %s", LOGFILE);
			}
			cleanup();
			do_exit(RC_SYSTEM_ERROR);
		} else {
			/* cannot happen, I think! */
			internal_error("driver exec'ing is confused");
			return;
		}
	}
}
Пример #2
0
void
run_phase (phases_t phase, char *name, string_list_t *args)
{
    const char **argv;
    int argc;
    string_item_t *p;
    char *output = NULL;
    char *input = NULL;
    boolean save_stderr = FALSE;
    int fdin, fdout;
    int waitstatus;
    int termsig;
    int num_maps;
    char *rld_path;
    struct stat stat_buf;
    const char* errmsg;
    int errnum;
    char *my_path;
    char *l_path;
    char *l32_path;
    char *nls_path;
    char *env_path;
    char *root_prefix;

#if defined(BUILD_OS_DARWIN)
    int suppress_compiler_path = (phase == P_gas);
#endif /* defined(BUILD_OS_DARWIN) */
    const boolean uses_message_system = 
            (phase == P_f90_fe || phase == P_cppf90_fe);

    if ((phase == P_be || phase == P_ipl) && add_heap_limit) {
        char str[200];

        sprintf(str, "-OPT:hugepage_heap_limit=%d -OPT:hugepage_attr=%d", 
			    heap_limit, hugepage_attr);
        add_string(args, str);
    }
    
    if (show_flag) {
        /* echo the command */
        fprintf(stderr, "%s ", name);
        print_string_list(stderr, args);
    }

    if (!execute_flag) return;

    if (time_flag) init_time();

    /* copy arg_list to argv format that exec wants */
    for (argc = 1, p = args->head; p != NULL; p = p->next) {
        //bug# 581, bug #932, bug #1049
        if (p->name == NULL || p->name[0] == '\0') {
            continue;
        }
        argc++;
    }
    argv = (const char **)malloc((argc + 1) * sizeof(char *));
    if (argv == NULL) {
        error("not enough memory");
        cleanup();
        do_exit(RC_SYSTEM_ERROR);
    }

    argv[0] = name;
    for (argc = 1, p = args->head; p != NULL; p = p->next) {
        //bug# 581, bug #932
        if (p->name == NULL || p->name[0] == '\0') {
            continue;
        }
        /* don't put redirection in arg list */
        if (strcmp(p->name, "<") == 0) {
            /* has input file */
            input = p->next->name;
            break;
        } else if (strcmp(p->name, ">") == 0) {
            /* has output file */
            output = p->next->name;
            break;
        } else if (strcmp(p->name, ">&") == 0) {
            /* has error output file */
            output = p->next->name;
            save_stderr = TRUE;
            break;
        }
        argv[argc++] = p->name;
    }
    argv[argc] = NULL;

    if (show_command_only(name, argv)) {
        return;
    }

    my_path = get_binutils_lib_path();
    rld_path = get_phase_ld_library_path(phase);
    
    if (rld_path != NULL) {
        asprintf(&my_path, "%s:%s", my_path, rld_path);
    }
    
    l_path = l32_path = my_path;
    
    if (ld_library_path) {
        asprintf(&l_path, "%s:%s", my_path, ld_library_path);
    }

    /* if we want memory stats, we have to wait for
       parent to connect to our /proc */
    if (input != NULL) {
    	if ((fdin = open (input, O_RDONLY)) == -1) {
            error ("cannot open input file %s", input);
            cleanup ();
            do_exit (RC_SYSTEM_ERROR);
            /* NOTREACHED */
    	}
    	dup2 (fdin, fileno(stdin));
    }
    if (output != NULL) {
    	if ((fdout = creat (output, 0666)) == -1) {
            error ("cannot create output file %s", output);
            cleanup ();
            do_exit (RC_SYSTEM_ERROR);
            /* NOTREACHED */
    	}
    	if (save_stderr) {
            dup2 (fdout, fileno(stderr));
    	} else {
            dup2 (fdout, fileno(stdout));
    	}
    } 
    
    my_path = get_binutils_lib_path();
    rld_path = get_phase_ld_library_path (phase);
    
    if (rld_path != 0) {
    	asprintf(&my_path, "%s:%s:%s/%s", my_path, rld_path, rld_path, current_target->abi_name);
    }
    
    l_path = l32_path = my_path;
    
    if (ld_library_path)
    	asprintf(&l_path, "%s:%s", my_path, ld_library_path);
    
    if (ld_libraryn32_path)
    	asprintf(&l32_path, "%s:%s", my_path,
    		 ld_libraryn32_path);

#if defined(BUILD_OS_DARWIN)
    /* Darwin static linker uses LD_LIBRARY_PATH, but dynamic
     * linker uses DYLD_LIBRARY_PATH */
    my_putenv("DYLD_LIBRARY_PATH", "%s", l_path);
#else /* defined(BUILD_OS_DARWIN) */
    my_putenv("LD_LIBRARY_PATH", "%s", l_path);
    my_putenv("LD_LIBRARYN32_PATH", "%s", l32_path);
#endif /* defined(BUILD_OS_DARWIN) */
		
    // Set up NLSPATH, for the Fortran front end.
    
    nls_path = getenv("NLSPATH");
    root_prefix = directory_path(get_executable_dir());
    
    if (nls_path) {
        my_putenv("NLSPATH", "%s:%s%s/%%N.cat", nls_path, root_prefix, LIBPATH);
    } else {
        my_putenv("NLSPATH", "%s%s/%%N.cat", root_prefix, LIBPATH);
    }
    
    if (uses_message_system && getenv("ORIG_CMD_NAME") == NULL)
        my_putenv("ORIG_CMD_NAME", "%s", program_name);
    
    if (phase == P_f90_fe) {
        char *root;
        char *modulepath;
        int len;
        char *new_env;
        char *env_name = "FORTRAN_SYSTEM_MODULES=";
        char *env_val = "/usr/lib/f90modules";
        root = getenv("TOOLROOT");
        if (root != NULL) {
            len = strlen(env_val) + strlen(root) +3 + strlen(env_val);
            new_env = alloca(len);
            sprintf(new_env,"%s/%s:%s",root,env_val,env_val);
            env_val = new_env;
        }
        modulepath = string_copy(getenv("FORTRAN_SYSTEM_MODULES"));
        if (modulepath != NULL) {
            /* Append env_val to FORTRAN_SYSTEM_MODULES */
            if (modulepath[strlen(modulepath)-1] == ':') {
                /* Just append env_val */
                len = strlen(modulepath) + strlen(env_val) + 1;
                new_env = alloca(len);
                sprintf(new_env,"%s%s",modulepath,env_val);
            } else {
                /* append :env_val */
                len = strlen(modulepath) + strlen(env_val) + 2;
                new_env = alloca(len);
                sprintf(new_env,"%s:%s",modulepath,env_val);
            }
            env_val = new_env;
        }
        
        my_putenv ("FORTRAN_SYSTEM_MODULES", "%s", env_val);
    }

    /* need to setenv COMPILER_PATH for collect to find ld */
    if (
#ifdef KEY
        // gcc will invoke the cc1 in the COMPILER_PATH directory,
        // which is not what we want when we invoke gcc for
        // preprocessing.  Bug 10164.

#if defined(BUILD_OS_DARWIN)
        /* Driver uses gcc to run assembler. If we set COMPILER_PATH,
         * gcc uses PSC version of cc1, which doesn't accept one of
         * the options (-mmacosx-version-min=10.5.1) which Apple's
         * gcc driver passes to Apple's cc1. Looks like the
         * "is_matching_phase" test might already be trying to fix
         * this, but it's not succeeding.
         */
        !suppress_compiler_path &&
#endif
        !is_matching_phase(get_phase_mask(P_any_cpp), phase) &&
#endif
        1) {
        my_putenv("COMPILER_PATH", "%s", get_phase_dir(P_collect));
    }

    /* Tell IPA where to find the driver. */
    my_putenv("COMPILER_BIN", "%s/" PSC_NAME_PREFIX "cc-"
              PSC_FULL_VERSION, get_executable_dir());

    if (execute(name, argv, input, output, &errmsg, &waitstatus) == -1) {
        error("execute failed: %s", errmsg);
        cleanup();
        do_exit(RC_SYSTEM_ERROR);
    }

    if (time_flag) print_time(name);
    
    if (WIFSTOPPED(waitstatus)) {
        error("STOPPED signal received from %s", name);
        cleanup();
        do_exit(RC_SYSTEM_ERROR);
        /* NOTREACHED */
    } else if (WIFEXITED(waitstatus)) {
        int status = WEXITSTATUS(waitstatus);
        extern int inline_t;
        boolean internal_err = FALSE;
        boolean user_err = FALSE;
        
        if (phase == P_prof) {
            /* Make sure the .cfb files were created before
               changing the STATUS to OKAY */
            if (prof_file != NULL) {
                if (!(stat(fb_file, &stat_buf) != 0 && errno == ENOENT)) {
                    status = RC_OKAY;
                }
            } else {
                internal_error("No count file was specified for a prof run");
                perror(program_name);
            }
        }
    
        if (phase == P_f90_fe && keep_listing) {
            char *cif_file = construct_given_name(drop_path(source_file), 
                                                  "T", TRUE);
    
            if (!(stat(cif_file, &stat_buf) != 0 && errno == ENOENT)) {
                f90_fe_status = status;
            }
            
            f90_fe_name = string_copy(name);
    
            /* Change the status to OKAY so that we can 
             * execute the lister on the cif_file; we will
             * take appropriate action on this status once 
             * the lister has finished executing. See below.
             */
            status = RC_OKAY;
        }
    
        if (phase == P_lister) {
            if (status == RC_OKAY && f90_fe_status != RC_OKAY) {
    
                /* We had encountered an error in the F90_fe phase
                 * but we ignored it so that we could execute the
                 * lister on the cif file; we need to switch the
                 * status to the status we received from F90_fe
                 * and use the name of the F90_fe_phase, so that
                 * we can issue a correct error message.
                 */
    
                status = f90_fe_status;
                name = string_copy(f90_fe_name);
    
                /* Reset f90_fe_status to OKAY for any further
                 * compilations on other source files.
                 */
    
                f90_fe_status = RC_OKAY;
            }
        }
    
        switch (status) {
        case RC_OKAY:
#ifdef KEY
            // If the command line has explicit inline
            // setting, follow it; else follow the
            // front-end request.  Bug 11325.
            if (inline_t != UNDEFINED) {
                run_inline = inline_t;
                break;
            }

#ifdef PATH64_ENABLE_GNU_FRONTEND
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_wgen)) {
              run_inline = FALSE;
            }
#endif // PATH64_ENABLE_GNU_FRONTEND
#ifdef PATH64_ENABLE_PSCLANG
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_psclang)) {
              run_inline = FALSE;
            }
#endif // PATH64_ENABLE_PSCLANG
            break;
#endif
            if (inline_t == UNDEFINED  && 
                is_matching_phase(get_phase_mask(phase), P_any_fe)) {
#ifdef KEY
                run_inline = FALSE; // bug 11325
#else
                inline_t = FALSE;
#endif
            }
            break;
        
        case RC_NEED_INLINER:
#ifdef KEY      // If the command line has explicit inline
            // setting, follow it; else follow the
            // front-end request.  Bug 11325.
            if (inline_t != UNDEFINED) {
                run_inline = inline_t;
                break;
            }

#ifdef PATH64_ENABLE_GNU_FRONTEND
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_wgen)) {
                run_inline = TRUE;
            }
#endif // PATH64_ENABLE_GNU_FRONTEND
#ifdef PATH64_ENABLE_PSCLANG
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_psclang)) {
              run_inline = TRUE;
            }
#endif // PATH64_ENABLE_PSCLANG
            break;

#endif
            if (inline_t == UNDEFINED && 
                is_matching_phase(get_phase_mask(phase), P_any_fe)) {
#ifdef KEY
                run_inline = TRUE;  // bug 11325
#else
                inline_t = TRUE;
#endif
            }
            /* completed successfully */
            break;
            
        case RC_USER_ERROR:
        case RC_NORECOVER_USER_ERROR:
        case RC_SYSTEM_ERROR:
        case RC_GCC_ERROR:
#ifdef KEY
        case RC_RTL_MISSING_ERROR: /* bug 14054 */
#endif
            user_err = TRUE;
            break;

        case RC_OVERFLOW_ERROR:
            if (!ran_twice && phase == P_be) {
                /* try recompiling with larger limits */
                ran_twice = TRUE;
                add_string(args, "-TENV:long_eh_offsets");
                add_string(args, "-TENV:large_stack");
                run_phase(phase, name, args);
                return;
            }
            internal_err = TRUE;
            break;
#ifdef KEY
        case RC_GCC_INTERNAL_ERROR:
#endif
        case RC_INTERNAL_ERROR:
            internal_err = TRUE;
            break;

        default:
            internal_err = TRUE;
            break;
        } 

        if (internal_err) {
            if (phase == P_ld ||
                phase == P_ldplus ||
#ifdef KEY
                phase == P_gas ||           // bug 4846
                phase == P_f_coco ||        // bug 9058
#ifdef PATH64_ENABLE_PSCLANG
                phase == P_psclang_cpp ||
                phase == P_psclang ||
#endif // PATH64_ENABLE_PSCLANG
                status == RC_GCC_INTERNAL_ERROR ||  //bug 9637
#endif // KEY
#ifdef PATH64_ENABLE_GNU_FRONTEND
                phase == P_spin_cc1 ||
                phase == P_spin_cc1plus ||
                phase == P_gcpp ||
                phase == P_gcpp_plus ||
#endif // PATH64_ENABLE_GNU_FRONTEND
                TRUE) {

                if (phase == P_gas ||
                    status == RC_GCC_INTERNAL_ERROR) {
                	internal_error_occurred = 1;
                }
                log_error("%s returned non-zero status %d", name, status);
                nomsg_error(status);
            } else {
                internal_error("%s returned non-zero status %d", name, status);
            }
        }
        else if (user_err) {
            /* assume phase will print diagnostics */
            if (phase == P_c_gfe || phase == P_cplus_gfe
#ifdef PATH64_ENABLE_GNU_FRONTEND
#ifdef KEY
                || phase == P_wgen
                || phase == P_spin_cc1
                || phase == P_spin_cc1plus
#endif // KEY
#endif // PATH64_ENABLE_GNU_FRONTEND
               ) {
                nomsg_error(RC_INTERNAL_ERROR);
            }
            else if (!show_flag || save_stderr) {
                nomsg_error(RC_USER_ERROR);
            } else {
                error("%s returned non-zero status %d", name, status);
            }
        }
        ran_twice = FALSE;
        return;

    } else if(WIFSIGNALED(waitstatus)) {
        termsig = WTERMSIG(waitstatus);
        switch (termsig) {
#ifdef SIGHUP
        case SIGHUP:
#endif
        case SIGINT:
#ifdef SIGQUIT
        case SIGQUIT:
#endif
#ifdef SIGKILL
        case SIGKILL:
#endif
        case SIGTERM:
            error("%s died due to signal %d", name, termsig);
            break;
        default:
            internal_error("%s died due to signal %d", name, termsig);
            break;
        }

        if(waitstatus & WCOREFLAG) {
            error("core dumped");
        }

#ifdef SIGKILL
        if (termsig == SIGKILL) {
            error("Probably caused by running out of swap space -- check %s", LOGFILE);
        }
#endif

        cleanup();
        do_exit(RC_SYSTEM_ERROR);
    } else {
        /* cannot happen, I think! */
        internal_error("driver exec'ing is confused");
        return;
    }
}