diff mbox

[C++] Fix ICE with initialized static volatile member (PR c++/51463)

Message ID 20111215172450.GP1957@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Dec. 15, 2011, 5:24 p.m. UTC
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  <jakub@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.


	Jakub

Comments

Jason Merrill Dec. 15, 2011, 7:41 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

--- 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" }
+};