OSDN Git Service

PR c++/29886
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Nov 2006 03:38:57 +0000 (03:38 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Nov 2006 03:38:57 +0000 (03:38 +0000)
* 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/trunk@119242 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/cast8.C [new file with mode: 0644]

index af4a3fc..095c2fe 100644 (file)
@@ -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.  
index c5dfea6..b6b1c97 100644 (file)
@@ -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;
 }
index 3adde52..f5cd43d 100644 (file)
@@ -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.
diff --git a/gcc/testsuite/g++.dg/expr/cast8.C b/gcc/testsuite/g++.dg/expr/cast8.C
new file mode 100644 (file)
index 0000000..9f1ce36
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/29886
+
+struct A {
+  static int x[1];
+};
+
+void foo(int i)
+{
+  if (int(A::x[i])) {}
+}
+