Hi!

The problem with this invalid testcase is that we first parse the
initializer taking into account the static storage class (i.e.
pass it as a normal static data member initializer), but later on
in grokdeclarator with error on static volatile being used together
and clear static because of it, and later on we attempt to use
the initializer as NSDMI, which ICEs.  grokdeclarator doesn't seem
to see the initializer, but if DECL_INITIAL is set to error_mark_node,
it will be ignored.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-12-15  Jakub Jelinek  <ja...@redhat.com>

        PR c++/51463
        * decl.c (grokdeclarator): Set DECL_INITIAL of decl
        to error_mark_node to disallow NSDMI if declspecs->storage_class
        is sc_static.
        * parser.c (cp_parser_late_parse_one_default_arg): Return early
        if default_arg is error_mark_node.

        * g++.dg/cpp0x/pr51463.C: New test.

--- gcc/cp/decl.c.jj    2011-12-08 16:36:49.000000000 +0100
+++ gcc/cp/decl.c       2011-12-14 17:27:32.144152053 +0100
@@ -10214,9 +10214,17 @@ grokdeclarator (const cp_declarator *dec
                  }
 
                if (initialized)
-                 /* An attempt is being made to initialize a non-static
-                    member.  This is new in C++11.  */
-                 maybe_warn_cpp0x (CPP0X_NSDMI);
+                 {
+                   /* An attempt is being made to initialize a non-static
+                      member.  This is new in C++11.  */
+                   maybe_warn_cpp0x (CPP0X_NSDMI);
+
+                   /* If this has been parsed with static storage class, but
+                      errors forced staticp to be cleared, ensure NSDMI is
+                      not present.  */
+                   if (declspecs->storage_class == sc_static)
+                     DECL_INITIAL (decl) = error_mark_node;
+                 }
              }
 
            bad_specifiers (decl, BSP_FIELD, virtualp,
--- gcc/cp/parser.c.jj  2011-12-14 08:10:59.000000000 +0100
+++ gcc/cp/parser.c     2011-12-14 17:30:51.150990128 +0100
@@ -21848,6 +21848,9 @@ cp_parser_late_parse_one_default_arg (cp
   tree parsed_arg;
   bool dummy;
 
+  if (default_arg == error_mark_node)
+    return error_mark_node;
+
   /* Push the saved tokens for the default argument onto the parser's
      lexer stack.  */
   tokens = DEFARG_TOKENS (default_arg);
--- gcc/testsuite/g++.dg/cpp0x/pr51463.C.jj     2011-12-14 17:33:37.034019780 
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr51463.C        2011-12-14 17:33:46.081967283 
+0100
@@ -0,0 +1,8 @@
+// PR c++/51463
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+struct A
+{
+  static virtual int i = 0;    // { dg-error "both virtual and static|declared 
as" }
+};

        Jakub

Reply via email to