c++ scoping problems

Matt Kraai kraai@alumni.carnegiemellon.edu
Tue Sep 25 16:15:00 GMT 2001


Howdy,

I've been investigating c++/4376, which reports a consistency
check failure compiling KDE.  I've reduced the problem to the
following testcase:

class Foo
{
public:
  Foo (int x);
  ~Foo ();
};

void
foo ()
{
  for (;;)
  {
    label: Foo bar(0);
  }
}

Because the for loop creates a scope, it uses the
already_scoped_stmt term.  This causes finish_compound_stmt to be
called with has_no_scope set to 1, which causes it not to
terminate the implicit scope created by a decl following a label.
As a result, the ending scope_stmt is emitted after the
compound_stmt, not as part of it, which then causes a nesting
level mismatch and hence a check failure.

I verified that replacing the occurences of already_scoped_decl by
implicitly_scoped_decl fixed this problem.  The patch follows at
the end of this message.  Unfortunately, I simultaneously realized
that all the C++ testcases were failing due to the __dso_handler
problem, so I can't test for execution regressions.

Does someone with a better understanding of C++ scoping know if
this is the correct solution, or if not what is?

Matt

Index: gcc/cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.226
diff -c -3 -p -r1.226 parse.y
*** parse.y	2001/09/21 01:26:55	1.226
--- parse.y	2001/09/25 23:09:56
*************** compstmtend:
*** 1178,1193 ****
  	| maybe_label_decls error '}'
  	;
  
- already_scoped_stmt:
- 	  save_lineno '{'
- 		{ $<ttype>$ =  begin_compound_stmt (1); }
- 	  compstmtend
- 		{ STMT_LINENO ($<ttype>3) = $1;
- 		  finish_compound_stmt (1, $<ttype>3); }
- 	| save_lineno simple_stmt
- 		{ if ($2) STMT_LINENO ($2) = $1; }
- 	;
- 
  nontrivial_exprlist:
  	  expr_no_commas ',' expr_no_commas
  		{ $$ = tree_cons (NULL_TREE, $$, 
--- 1178,1183 ----
*************** simple_stmt:
*** 3385,3391 ****
  		}
  	  paren_cond_or_null
                  { finish_while_stmt_cond ($3, $<ttype>2); }
! 	  already_scoped_stmt
                  { $$ = $<ttype>2;
  		  finish_while_stmt ($<ttype>2); }
  	| DO
--- 3375,3381 ----
  		}
  	  paren_cond_or_null
                  { finish_while_stmt_cond ($3, $<ttype>2); }
! 	  implicitly_scoped_stmt
                  { $$ = $<ttype>2;
  		  finish_while_stmt ($<ttype>2); }
  	| DO
*************** simple_stmt:
*** 3406,3412 ****
                  { finish_for_cond ($6, $<ttype>2); }
  	  xexpr ')'
                  { finish_for_expr ($9, $<ttype>2); }
! 	  already_scoped_stmt
                  { $$ = $<ttype>2;
  		  finish_for_stmt ($<ttype>2); }
  	| SWITCH 
--- 3396,3402 ----
                  { finish_for_cond ($6, $<ttype>2); }
  	  xexpr ')'
                  { finish_for_expr ($9, $<ttype>2); }
! 	  implicitly_scoped_stmt
                  { $$ = $<ttype>2;
  		  finish_for_stmt ($<ttype>2); }
  	| SWITCH 



More information about the Gcc-patches mailing list