re PR c++/18126 (sizeof compound-literal not parsed correctly)
authorPaolo Carlini <paolo.carlini@oracle.com>
Fri, 17 May 2013 12:35:44 +0000 (12:35 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Fri, 17 May 2013 12:35:44 +0000 (12:35 +0000)
/cp
2013-05-17  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/18126
* parser.c (cp_parser_sizeof_operand): As a GNU Extension, parse
correctly sizeof compound-literal; update comments.

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

PR c++/18126
* g++.dg/ext/sizeof-complit.C: New.

From-SVN: r199012

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/sizeof-complit.C [new file with mode: 0644]

index ab2afd489787ca6056bf86cfbeb563cc6fef0a18..14093eb935f7efb97bcdb4af29555cfafb1ffa1e 100644 (file)
@@ -1,3 +1,9 @@
+2013-05-17  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/18126
+       * parser.c (cp_parser_sizeof_operand): As a GNU Extension, parse
+       correctly sizeof compound-literal; update comments.
+
 2013-05-16  Marc Glisse  <marc.glisse@inria.fr>
 
        * call.c (build_conditional_expr_1): Use cp_build_binary_op
index 0a075b221cfefbbd4b21a67f7ea7d09103876f56..022886e37b6f2b2100068949cb4bbc32881b29e6 100644 (file)
@@ -6591,6 +6591,9 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
      __real__ cast-expression
      __imag__ cast-expression
      && identifier
+     sizeof ( type-id ) { initializer-list , [opt] }
+     alignof ( type-id ) { initializer-list , [opt] } [C++0x]
+     __alignof__ ( type-id ) { initializer-list , [opt] }
 
    ADDRESS_P is true iff the unary-expression is appearing as the
    operand of the `&' operator.   CAST_P is true if this expression is
@@ -13968,6 +13971,7 @@ cp_parser_type_specifier (cp_parser* parser,
      __int128
      __typeof__ unary-expression
      __typeof__ ( type-id )
+     __typeof__ ( type-id ) { initializer-list , [opt] }
 
    Returns the indicated TYPE_DECL.  If DECL_SPECS is not NULL, it is
    appropriately updated.  */
@@ -22988,21 +22992,44 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
      construction.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
-      tree type;
-      bool saved_in_type_id_in_expr_p;
+      tree type = NULL_TREE;
+      bool compound_literal_p;
 
       /* We can't be sure yet whether we're looking at a type-id or an
         expression.  */
       cp_parser_parse_tentatively (parser);
       /* Consume the `('.  */
       cp_lexer_consume_token (parser->lexer);
-      /* Parse the type-id.  */
-      saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
-      parser->in_type_id_in_expr_p = true;
-      type = cp_parser_type_id (parser);
-      parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
-      /* Now, look for the trailing `)'.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+      /* Note: as a GNU Extension, compound literals are considered
+        postfix-expressions as they are in C99, so they are valid
+        arguments to sizeof.  See comment in cp_parser_cast_expression
+        for details.  */
+      cp_lexer_save_tokens (parser->lexer);
+      /* Skip tokens until the next token is a closing parenthesis.
+        If we find the closing `)', and the next token is a `{', then
+        we are looking at a compound-literal.  */
+      compound_literal_p
+       = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
+                                                 /*consume_paren=*/true)
+          && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
+      /* Roll back the tokens we skipped.  */
+      cp_lexer_rollback_tokens (parser->lexer);
+      /* If we were looking at a compound-literal, simulate an error
+        so that the call to cp_parser_parse_definitely below will
+        fail.  */
+      if (compound_literal_p)
+       cp_parser_simulate_error (parser);
+      else
+       {
+         bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+         parser->in_type_id_in_expr_p = true;
+         /* Look for the type-id.  */
+         type = cp_parser_type_id (parser);
+         /* Look for the closing `)'.  */
+         cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+         parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+       }
+
       /* If all went well, then we're done.  */
       if (cp_parser_parse_definitely (parser))
        {
index dfe29773ca9abf85c4c269363e4df900635e4a07..b2ec2636c7a5c0e3fb042f88175adbf815820564 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-17  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/18126
+       * g++.dg/ext/sizeof-complit.C: New.
+
 2013-05-17  Marek Polacek  <polacek@redhat.com>
 
        * gcc.dg/strlenopt-25.c: New test.
diff --git a/gcc/testsuite/g++.dg/ext/sizeof-complit.C b/gcc/testsuite/g++.dg/ext/sizeof-complit.C
new file mode 100644 (file)
index 0000000..6cf6d4e
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/18126
+// { dg-options "" }
+
+struct s { int a; int b; };
+char x[((sizeof (struct s){ 1, 2 }) == sizeof (struct s)) ? 1 : -1];