C parser breakage due to c99 block scopes

Zack Weinberg zackw@stanford.edu
Thu Nov 16 18:17:00 GMT 2000


Current CVS crashes when compiling dwarf2out.c ("Error reporting
routines re-entered").  This is a segfault inside diagnostic.c, called
from here (lines 1844-1851 of c-parse.in):

	    { c_expand_end_cond ();
	      /* This warning is here instead of in simple_if, because we
		 do not want a warning if an empty if is followed by an
		 else statement.  Increment stmt_count so we don't
		 give a second error if this is a nested `if'.  */
	      if (extra_warnings && stmt_count++ == $<itype>1)
		warning_with_file_and_line (if_stmt_file, if_stmt_line,
					"empty body in an if-statement"); }

if_stmt_file is garbage - well, actually, if_stmt_file has the numeric
value that if_stmt_line should've had, which of course is an invalid
pointer.

i_s_f/i_s_l are set here:

if_prefix:
	  IF '(' expr ')'
		{ c_expand_start_cond (truthvalue_conversion ($3), 
				       compstmt_count);
		  $<itype>$ = stmt_count;
		  if_stmt_file = $<filename>-1;
		  if_stmt_line = $<lineno>0; }
	;

This rule anticipates being used immediately after save_filename and
save_lineno, e.g.

simple_if:	save_filename save_lineno if_prefix /* ... */

However, that's not the way it's being used.  If you trace rules back
upward, you find this (all actions deleted for clarity):

simple_if:
	  if_prefix c99_block_lineno_labeled_stmt

select_or_iter_stmt:
	  simple_if ELSE c99_block_lineno_labeled_stmt
	  | simple_if
	  | simple_if ELSE error
	  | WHILE
	  ...  /* nothing else involving simple_if */

stmt:
	compstmt
	| expr ';'
	| c99_block_start select_or_iter_stmt c99_block_end


lineno_labeled_stmt:
	  save_filename save_lineno stmt
lineno_stmt:
	  save_filename save_lineno stmt

(As an aside, the lineno_labeled_stmt rule looks utterly broken on its
face, but never mind.)  The point is that c99_block_start appears
between the save_filename/save_lineno pair, and simple_if.  As
c99_block_stmt pushes a value onto the stack, the indexes in if_prefix
will be off by one.

These are the only uses of if_prefix, simple_if, etc. in the file, so
I believe the simplest fix is to change the if_prefix action so it
uses $<filename>-2 and $<lineno>-1 instead of -1 and 0.  However, I'd
like us to think about getting rid of this insanely fragile line-
number-remembering scheme as soon as feasible.

zw


More information about the Gcc-bugs mailing list