The driver gcc.c has 2 internal error reporting routines perror_with_name & pfatal_with_name, which take a single string argument.

Firstly the latter forwards to the former, then calls exit after doing some cleanup. However, that cleanup is already registered via atexit, so it'll get done anyway.

More problematic is that the single string doesn't allow context of the problem to be shown. For instance we get:
   nathans@lyta:17>gcc -specs=not-a-file insn-emit.c
   gcc: error: not-a-file: No such file or directory

This patch removes those two functions and just calls error or fatal_error as appropriate. We now get:
   nathans@lyta:16>./xg++ -B./ -specs=not-a-file insn-emit.c
xg++: fatal error: cannot read spec file 'not-a-file': No such file or directory
   compilation terminated.

I'm not sure if pex_run can return a non-null errmsg with zero error code, but I've left that alone. In the case of spec file reading, we were already leaving the file handle open on some of the failure cases. I'm not making that worse. Likewise the message in process_command that concerns response files could probably be made better, but I'm not sure what it's trying to say.

booted & tested on x86_64-linux, installing as obvious.

nathan
--
Nathan Sidwell
2018-09-11  Nathan Sidwell  <nat...@acm.org>

	* gcc.c (perror_with_name, pfatal_with_name): Delete.
	(load_specs): Use fatal_error.
	(DELETE_IF_ORDINARY, process_command): Use error.
	(execute, run_attempt): Use fatal_error.

	* gcc.dg/driver-specs.c: New.

Index: gcc.c
===================================================================
--- gcc.c	(revision 264178)
+++ gcc.c	(working copy)
@@ -372,8 +372,6 @@ static void give_switch (int, int);
 static int default_arg (const char *, int);
 static void set_multilib_dir (void);
 static void print_multilib_info (void);
-static void perror_with_name (const char *);
-static void pfatal_with_name (const char *) ATTRIBUTE_NORETURN;
 static void display_help (void);
 static void add_preprocessor_option (const char *, int);
 static void add_assembler_option (const char *, int);
@@ -2101,15 +2099,20 @@ load_specs (const char *filename)
   /* Open and stat the file.  */
   desc = open (filename, O_RDONLY, 0);
   if (desc < 0)
-    pfatal_with_name (filename);
+    {
+    failed:
+      /* This leaves DESC open, but the OS will save us.  */
+      fatal_error (input_location, "cannot read spec file '%s': %m", filename);
+    }
+
   if (stat (filename, &statbuf) < 0)
-    pfatal_with_name (filename);
+    goto failed;
 
   /* Read contents of file into BUFFER.  */
   buffer = XNEWVEC (char, statbuf.st_size + 1);
   readlen = read (desc, buffer, (unsigned) statbuf.st_size);
   if (readlen < 0)
-    pfatal_with_name (filename);
+    goto failed;
   buffer[readlen] = 0;
   close (desc);
 
@@ -2490,7 +2493,7 @@ do
     if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode))  \
       if (unlink (NAME) < 0)                            \
 	if (VERBOSE_FLAG)                               \
-	  perror_with_name (NAME);                      \
+	  error ("%s: %m", (NAME));			\
   } while (0)
 #endif
 
@@ -3169,13 +3172,11 @@ execute (void)
 			NULL, NULL, &err);
       if (errmsg != NULL)
 	{
-	  if (err == 0)
-	    fatal_error (input_location, errmsg);
-	  else
-	    {
-	      errno = err;
-	      pfatal_with_name (errmsg);
-	    }
+	  errno = err;
+	  fatal_error (input_location,
+		       err ? G_("cannot execute '%s' %s: %m")
+		       : G_("cannot execute '%s' %s"),
+		       string, errmsg);
 	}
 
       if (i && string != commands[i].prog)
@@ -4545,10 +4546,8 @@ process_command (unsigned int decoded_op
 
           if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
 	    {
-	      if (fname[0] == '@' && access (fname + 1, F_OK) < 0)
-		perror_with_name (fname + 1);
-	      else
-		perror_with_name (fname);
+	      bool resp = fname[0] == '@' && access (fname + 1, F_OK) < 0;
+	      error ("%s: %m", fname + resp);
 	    }
           else
 	    add_infile (arg, spec_lang);
@@ -6886,13 +6885,11 @@ run_attempt (const char **new_argv, cons
 		    err_temp, &err);
   if (errmsg != NULL)
     {
-      if (err == 0)
-	fatal_error (input_location, errmsg);
-      else
-	{
-	  errno = err;
-	  pfatal_with_name (errmsg);
-	}
+      errno = err;
+      fatal_error (input_location,
+		   err ? G_ ("cannot execute '%s' %s: %m")
+		   : G_ ("cannot execute '%s' %s"),
+		   new_argv[0], errmsg);
     }
 
   if (!pex_get_status (pex, 1, &exit_status))
@@ -8407,19 +8404,6 @@ save_string (const char *s, int len)
   return result;
 }
 
-void
-pfatal_with_name (const char *name)
-{
-  perror_with_name (name);
-  delete_temp_files ();
-  exit (1);
-}
-
-static void
-perror_with_name (const char *name)
-{
-  error ("%s: %m", name);
-}
 
 static inline void
 validate_switches_from_spec (const char *spec, bool user)
Index: testsuite/gcc.dg/driver-specs.c
===================================================================
--- testsuite/gcc.dg/driver-specs.c	(nonexistent)
+++ testsuite/gcc.dg/driver-specs.c	(working copy)
@@ -0,0 +1,4 @@
+// { dg-additional-options "-specs=not-a-file" }
+// { dg-prune-output "compilation terminated" }
+// { dg-error "cannot read spec file" "" { target *-*-* } 0 }
+

Reply via email to