Patchwork [C++] PR 10207

login
register
mail settings
Submitter Paolo Carlini
Date May 18, 2013, 2:14 a.m.
Message ID <5196E3F4.5050707@oracle.com>
Download mbox | patch
Permalink /patch/244722/
State New
Headers show

Comments

Paolo Carlini - May 18, 2013, 2:14 a.m.
Hi,

in this even older ;) and related issue, we reject empty initializer 
lists in compound-literals. The fix seems simple: just use 
cp_parser_braced_list instead of cp_parser_initializer_list, which 
allows for the special case of empty list. Tested x86_64-linux.

There is a nit which I don't want to hide: cp_parser_initializer_list + 
build_constructor does a little more than cp_parser_braced_list: in 
build_constructor there is a loop setting TREE_SIDE_EFFECTS and 
TREE_CONSTANT to the right value for the CONSTRUCTOR overall, which 
doesn't exist in cp_parser_braced_list. In case it matters - I don't 
think it does, and we have testcases with side effects in the testsuite 
- we can't simply add it to cp_parser_braced_list, because its many 
existing uses are perfectly fine without. A little more code would be 
needed, not a big issue.

Thanks,
Paolo.

///////////////////////
/cp
2013-05-18  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/10207
	* parser.c (cp_parser_postfix_expression): Use cp_parser_braced_list
	instead of cp_parser_initializer_list for compound-literals.

/testsuite
2013-05-18  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/10207
	* g++.dg/ext/complit13.C: New.
Jason Merrill - May 20, 2013, 1:43 a.m.
OK.

Jason

Patch

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 199043)
+++ cp/parser.c	(working copy)
@@ -5719,7 +5719,7 @@  cp_parser_postfix_expression (cp_parser *parser, b
 	if (cp_parser_allow_gnu_extensions_p (parser)
 	    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
 	  {
-	    vec<constructor_elt, va_gc> *initializer_list = NULL;
+	    tree initializer = NULL_TREE;
 	    bool saved_in_type_id_in_expr_p;
 
 	    cp_parser_parse_tentatively (parser);
@@ -5732,21 +5732,19 @@  cp_parser_postfix_expression (cp_parser *parser, b
 	    parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
 	    /* Look for the `)'.  */
 	    cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
-	    /* Look for the `{'.  */
-	    cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
 	    /* If things aren't going well, there's no need to
 	       keep going.  */
 	    if (!cp_parser_error_occurred (parser))
 	      {
-		bool non_constant_p;
-		/* Parse the initializer-list.  */
-		initializer_list
-		  = cp_parser_initializer_list (parser, &non_constant_p);
-		/* Allow a trailing `,'.  */
-		if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
-		  cp_lexer_consume_token (parser->lexer);
-		/* Look for the final `}'.  */
-		cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+		if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+		  {
+		    bool non_constant_p;
+		    /* Parse the brace-enclosed initializer list.  */
+		    initializer = cp_parser_braced_list (parser,
+							 &non_constant_p);
+		  }
+		else
+		  cp_parser_simulate_error (parser);
 	      }
 	    /* If that worked, we're definitely looking at a
 	       compound-literal expression.  */
@@ -5754,7 +5752,8 @@  cp_parser_postfix_expression (cp_parser *parser, b
 	      {
 		/* Warn the user that a compound literal is not
 		   allowed in standard C++.  */
-		pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids compound-literals");
+		pedwarn (input_location, OPT_Wpedantic,
+			 "ISO C++ forbids compound-literals");
 		/* For simplicity, we disallow compound literals in
 		   constant-expressions.  We could
 		   allow compound literals of integer type, whose
@@ -5772,10 +5771,8 @@  cp_parser_postfix_expression (cp_parser *parser, b
 		  }
 		/* Form the representation of the compound-literal.  */
 		postfix_expression
-		  = (finish_compound_literal
-		     (type, build_constructor (init_list_type_node,
-					       initializer_list),
-		      tf_warning_or_error));
+		  = (finish_compound_literal (type, initializer,
+					      tf_warning_or_error));
 		break;
 	      }
 	  }
Index: testsuite/g++.dg/ext/complit13.C
===================================================================
--- testsuite/g++.dg/ext/complit13.C	(revision 0)
+++ testsuite/g++.dg/ext/complit13.C	(working copy)
@@ -0,0 +1,11 @@ 
+// PR c++/10207
+// { dg-options "" }
+
+typedef struct { } EmptyStruct;
+typedef struct { EmptyStruct Empty; } DemoStruct;
+
+void Func()
+{
+  DemoStruct Demo;
+  Demo.Empty = (EmptyStruct) {};
+}