This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix for confusing error message upon unreadable source file


Currently, if you attempt to compile an unreadable source file, you
get this:

$ echo 'int foo;' >test.c
$ chmod 0 test.c
$ ./cc1 -quiet test.c
cc1: test.c: Permission denied
Errors detected in input file (your bison.simple is out of date)

The second message is false and confusing.  It is being caused by a
very old sanity check in toplev.c:

  if (yyparse () != 0)
    {
      if (errorcount == 0)
	fnotice (stderr,
    "Errors detected in input file (your bison.simple is out of date)\n");

which is intended to catch a situation where a Yacc-based parser
detected an error but failed to report it properly by calling error().
I guess that used to happen with older buggy versions of bison.  The
"Permission denied" error is coming from cpplib, which maintains a
separate error counter.  errorcount will be updated from it, but not
until much later, in finish_parse.  Therefore yyparse correctly
returns nonzero, errorcount is indeed zero, but the sanity check has
misfired - the user has been informed of the real problem, and
errorcount will be correct by the time we go to call exit().

In addition to this problem, the sanity check is of dubious value in
the present day.  We are moving away from Yacc-generated parsers.  A
hand-written recursive descent parser probably doesn't want to bother
passing error status all the way back up, it will just have yyparse
return zero always.  (The Fortran front end does this right now, and
the new C++ parser would like to do the same.)  There is some
error-recovery logic also predicated on yyparse returning nonzero,
which will not fire when it should with such a parser.

For these reasons, I propose to dump the sanity check and run the
error recovery logic always.  (It does nothing if there aren't stray
nested scopes to get out of.)  The appended patch does this.

Bootstrapped i686-linux.  OK to apply?

zw

	* toplev.c (compile_file): Ignore return value from yyparse.
	Always pop any nested binding levels after yyparse returns.

===================================================================
Index: toplev.c
--- toplev.c	2001/10/11 03:16:10	1.519
+++ toplev.c	2001/10/11 21:26:16
@@ -2118,8 +2118,9 @@ pop_srcloc ()
   lineno = input_file_stack->line;
 }
 
-/* Compile an entire file of output from cpp, named NAME.
-   Write a file of assembly output and various debugging dumps.  */
+/* Compile an entire translation unit, whose primary source file is
+   named NAME.  Write a file of assembly output and various debugging
+   dumps.  */
 
 static void
 compile_file (name)
@@ -2140,7 +2141,7 @@ compile_file (name)
   init_timevar ();
   timevar_start (TV_TOTAL);
 
-  /* Open assembler code output file.  Do this even if -fsyntax-only is on,
+  /* Open assembly code output file.  Do this even if -fsyntax-only is on,
      because then the driver will have provided the name of a temporary
      file or bit bucket for us.  */
 
@@ -2324,17 +2325,12 @@ compile_file (name)
 
   /* Call the parser, which parses the entire file
      (calling rest_of_compilation for each function).  */
+  yyparse ();
 
-  if (yyparse () != 0)
-    {
-      if (errorcount == 0)
-	fnotice (stderr, "Errors detected in input file (your bison.simple is out of date)\n");
-
-      /* In case there were missing closebraces,
-	 get us back to the global binding level.  */
-      while (! global_bindings_p ())
-	poplevel (0, 0, 0);
-    }
+  /* In case there were missing block closers,
+     get us back to the global binding level.  */
+  while (! global_bindings_p ())
+    poplevel (0, 0, 0);
 
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]