From: Mark Mitchell Date: Mon, 27 Nov 2006 03:38:57 +0000 (+0000) Subject: re PR c++/29886 (Cast misinterpreted as variable declaration) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=56c7f9c1d073eb17e95c171e945bfabb322ca5f1;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index af4a3fc399f..095c2fe5527 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2006-11-26 Mark Mitchell + + 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 * cp-tree.def (STATIC_ASSERT): New. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c5dfea60825..b6b1c972921 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3adde52429f..f5cd43d3965 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-11-26 Mark Mitchell + + PR c++/29886 + * g++.dg/expr/cast8.C: New test. + 2006-11-26 Kaveh R. Ghazi * gcc.dg/torture/builtin-minmax-1.c: Test NaN in fmin/fmax. diff --git a/gcc/testsuite/g++.dg/expr/cast8.C b/gcc/testsuite/g++.dg/expr/cast8.C new file mode 100644 index 00000000000..9f1ce36f487 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cast8.C @@ -0,0 +1,11 @@ +// PR c++/29886 + +struct A { + static int x[1]; +}; + +void foo(int i) +{ + if (int(A::x[i])) {} +} +