From 8952fce4364223372773c792bd5ec77b0be58781 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Mon, 27 Nov 2006 04:56:02 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_2-branch@119244 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 15 +++++++++++++++ gcc/cp/parser.c | 28 ++++++++++++++++++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/expr/cast8.C | 11 +++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/cast8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4c0928c459c..32a6b70706b 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 Jakub Jelinek PR c++/29570 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8d25db680fc..e0348c48e75 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. */ @@ -2632,6 +2636,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); @@ -2988,7 +2995,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 (); @@ -10879,7 +10886,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))) { @@ -10945,7 +10952,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); @@ -11625,7 +11632,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; @@ -13007,6 +13014,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; @@ -13041,6 +13049,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) @@ -13149,7 +13160,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; @@ -15303,7 +15315,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); @@ -15493,8 +15505,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. */ @@ -15548,6 +15563,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 f521d993263..db8ae033911 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 Andrew Pinski PR fortran/29982 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])) {} +} + -- 2.11.4.GIT