re PR c++/29886 (Cast misinterpreted as variable declaration)
PR c++/29886 * parser.c (cp_parser): Add in_function_body. (cp_parser_new): Initialize it. (cp_parser_primary_expression): Use parser->in_function_body instead of at_function_scope_p. (cp_parser_asm_definition): Likewise. (cp_parser_direct_declarator): Likewise. (cp_parser_class_specifier): Clear parser->in_function_body. (cp_parser_constructor_declarator_p): Use parser->in_function_body instead of at_function_scope_p. (cp_parser_function_body_after_declarator): Set parser->in_function_body. PR c++/29886 * g++.dg/expr/cast8.C: New test. From-SVN: r119242
This commit is contained in:
parent
f019376cf5
commit
56c7f9c1d0
4 changed files with 53 additions and 6 deletions
|
@ -1,3 +1,18 @@
|
|||
2006-11-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/29886
|
||||
* parser.c (cp_parser): Add in_function_body.
|
||||
(cp_parser_new): Initialize it.
|
||||
(cp_parser_primary_expression): Use parser->in_function_body
|
||||
instead of at_function_scope_p.
|
||||
(cp_parser_asm_definition): Likewise.
|
||||
(cp_parser_direct_declarator): Likewise.
|
||||
(cp_parser_class_specifier): Clear parser->in_function_body.
|
||||
(cp_parser_constructor_declarator_p): Use parser->in_function_body
|
||||
instead of at_function_scope_p.
|
||||
(cp_parser_function_body_after_declarator): Set
|
||||
parser->in_function_body.
|
||||
|
||||
2006-11-21 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
* cp-tree.def (STATIC_ASSERT): New.
|
||||
|
|
|
@ -1390,6 +1390,10 @@ typedef struct cp_parser GTY(())
|
|||
character set. */
|
||||
bool translate_strings_p;
|
||||
|
||||
/* TRUE if we are presently parsing the body of a function, but not
|
||||
a local class. */
|
||||
bool in_function_body;
|
||||
|
||||
/* If non-NULL, then we are parsing a construct where new type
|
||||
definitions are not permitted. The string stored here will be
|
||||
issued as an error message if a type is defined. */
|
||||
|
@ -2634,6 +2638,9 @@ cp_parser_new (void)
|
|||
/* String literals should be translated to the execution character set. */
|
||||
parser->translate_strings_p = true;
|
||||
|
||||
/* We are not parsing a function body. */
|
||||
parser->in_function_body = false;
|
||||
|
||||
/* The unparsed function queue is empty. */
|
||||
parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE);
|
||||
|
||||
|
@ -2990,7 +2997,7 @@ cp_parser_primary_expression (cp_parser *parser,
|
|||
int i = ({ int j = 3; j + 1; });
|
||||
|
||||
at class or namespace scope. */
|
||||
if (!at_function_scope_p ())
|
||||
if (!parser->in_function_body)
|
||||
error ("statement-expressions are allowed only inside functions");
|
||||
/* Start the statement-expression. */
|
||||
expr = begin_stmt_expr ();
|
||||
|
@ -10952,7 +10959,7 @@ cp_parser_asm_definition (cp_parser* parser)
|
|||
too. Doing that means that we have to treat the `::' operator as
|
||||
two `:' tokens. */
|
||||
if (cp_parser_allow_gnu_extensions_p (parser)
|
||||
&& at_function_scope_p ()
|
||||
&& parser->in_function_body
|
||||
&& (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
|
||||
|| cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
|
||||
{
|
||||
|
@ -11018,7 +11025,7 @@ cp_parser_asm_definition (cp_parser* parser)
|
|||
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
|
||||
|
||||
/* Create the ASM_EXPR. */
|
||||
if (at_function_scope_p ())
|
||||
if (parser->in_function_body)
|
||||
{
|
||||
asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
|
||||
inputs, clobbers);
|
||||
|
@ -11698,7 +11705,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
/* Normally, the array bound must be an integral constant
|
||||
expression. However, as an extension, we allow VLAs
|
||||
in function scopes. */
|
||||
else if (!at_function_scope_p ())
|
||||
else if (!parser->in_function_body)
|
||||
{
|
||||
error ("array bound is not an integer constant");
|
||||
bounds = error_mark_node;
|
||||
|
@ -13080,6 +13087,7 @@ cp_parser_class_specifier (cp_parser* parser)
|
|||
int has_trailing_semicolon;
|
||||
bool nested_name_specifier_p;
|
||||
unsigned saved_num_template_parameter_lists;
|
||||
bool saved_in_function_body;
|
||||
tree old_scope = NULL_TREE;
|
||||
tree scope = NULL_TREE;
|
||||
|
||||
|
@ -13114,6 +13122,9 @@ cp_parser_class_specifier (cp_parser* parser)
|
|||
saved_num_template_parameter_lists
|
||||
= parser->num_template_parameter_lists;
|
||||
parser->num_template_parameter_lists = 0;
|
||||
/* We are not in a function body. */
|
||||
saved_in_function_body = parser->in_function_body;
|
||||
parser->in_function_body = false;
|
||||
|
||||
/* Start the class. */
|
||||
if (nested_name_specifier_p)
|
||||
|
@ -13222,7 +13233,8 @@ cp_parser_class_specifier (cp_parser* parser)
|
|||
/* Put back any saved access checks. */
|
||||
pop_deferring_access_checks ();
|
||||
|
||||
/* Restore the count of active template-parameter-lists. */
|
||||
/* Restore saved state. */
|
||||
parser->in_function_body = saved_in_function_body;
|
||||
parser->num_template_parameter_lists
|
||||
= saved_num_template_parameter_lists;
|
||||
|
||||
|
@ -15388,7 +15400,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
|
|||
/* The common case is that this is not a constructor declarator, so
|
||||
try to avoid doing lots of work if at all possible. It's not
|
||||
valid declare a constructor at function scope. */
|
||||
if (at_function_scope_p ())
|
||||
if (parser->in_function_body)
|
||||
return false;
|
||||
/* And only certain tokens can begin a constructor declarator. */
|
||||
next_token = cp_lexer_peek_token (parser->lexer);
|
||||
|
@ -15578,8 +15590,11 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
|
|||
tree fn;
|
||||
bool ctor_initializer_p = false;
|
||||
bool saved_in_unbraced_linkage_specification_p;
|
||||
bool saved_in_function_body;
|
||||
unsigned saved_num_template_parameter_lists;
|
||||
|
||||
saved_in_function_body = parser->in_function_body;
|
||||
parser->in_function_body = true;
|
||||
/* If the next token is `return', then the code may be trying to
|
||||
make use of the "named return value" extension that G++ used to
|
||||
support. */
|
||||
|
@ -15633,6 +15648,7 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
|
|||
= saved_in_unbraced_linkage_specification_p;
|
||||
parser->num_template_parameter_lists
|
||||
= saved_num_template_parameter_lists;
|
||||
parser->in_function_body = saved_in_function_body;
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2006-11-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/29886
|
||||
* g++.dg/expr/cast8.C: New test.
|
||||
|
||||
2006-11-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* gcc.dg/torture/builtin-minmax-1.c: Test NaN in fmin/fmax.
|
||||
|
|
11
gcc/testsuite/g++.dg/expr/cast8.C
Normal file
11
gcc/testsuite/g++.dg/expr/cast8.C
Normal file
|
@ -0,0 +1,11 @@
|
|||
// PR c++/29886
|
||||
|
||||
struct A {
|
||||
static int x[1];
|
||||
};
|
||||
|
||||
void foo(int i)
|
||||
{
|
||||
if (int(A::x[i])) {}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue