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