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.carl...@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.carl...@oracle.com>

        PR c++/10207
        * g++.dg/ext/complit13.C: New.
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) {};
+}

Reply via email to