Hi!

The initializer for structured binding has to be one of:
= assignment-expression
( assignment-expression )
{ assignment-expression }
but cp_parser_initializer can parse other forms, with fewer or more
expressions in there.  Some cases we caught with various cryptic errors
or pedwarns, but others we just ICEd on.

The following patch attempts to check this.

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

2017-06-30  Jakub Jelinek  <ja...@redhat.com>

        PR c++/81258
        * parser.c (cp_parser_decomposition_declaration): Diagnose invalid
        forms of structured binding initializers.

        * g++.dg/cpp1z/decomp21.C (foo): Adjust expected diagnostics.
        * g++.dg/cpp1z/decomp30.C: New test.

--- gcc/cp/parser.c.jj  2017-06-30 09:49:25.000000000 +0200
+++ gcc/cp/parser.c     2017-06-30 11:03:18.526521000 +0200
@@ -13196,6 +13196,15 @@ cp_parser_decomposition_declaration (cp_
       *init_loc = cp_lexer_peek_token (parser->lexer)->location;
       tree initializer = cp_parser_initializer (parser, &is_direct_init,
                                                &non_constant_p);
+      if (initializer == NULL_TREE
+         || (TREE_CODE (initializer) == TREE_LIST
+             && TREE_CHAIN (initializer))
+         || (TREE_CODE (initializer) == CONSTRUCTOR
+             && CONSTRUCTOR_NELTS (initializer) != 1))
+       {
+         error_at (loc, "invalid initializer for structured binding");
+         initializer = error_mark_node;
+       }
 
       if (decl != error_mark_node)
        {
--- gcc/testsuite/g++.dg/cpp1z/decomp21.C.jj    2017-01-19 17:01:21.000000000 
+0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp21.C       2017-06-30 11:07:04.786746784 
+0200
@@ -12,5 +12,5 @@ foo ()
   auto [ n, o, p ] { a };
   auto [ q, r, t ] ( s );
   auto [ u, v, w ] ( s, );      // { dg-error "expected primary-expression 
before '.' token" }
-  auto [ x, y, z ] ( a );       // { dg-error "expression list treated as 
compound expression in initializer" "" { target *-*-* } .-1 }
+  auto [ x, y, z ] ( a );       // { dg-error "invalid initializer for 
structured binding" "" { target *-*-* } .-1 }
 }
--- gcc/testsuite/g++.dg/cpp1z/decomp30.C.jj    2017-06-30 11:09:31.934942575 
+0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp30.C       2017-06-30 11:09:22.000000000 
+0200
@@ -0,0 +1,12 @@
+// PR c++/81258
+// { dg-options -std=c++1z }
+
+int a[2];
+auto [b, c] (a);
+auto [d, e] { a };
+auto [f, g] = a;
+auto [h, i] ( a, a );  // { dg-error "invalid initializer for structured 
binding" }
+auto [j, k] { a, a };  // { dg-error "invalid initializer for structured 
binding" }
+auto [l, m] = { a };   // { dg-error "deducing from brace-enclosed initializer 
list requires" }
+auto [n, o] {};                // { dg-error "invalid initializer for 
structured binding" }
+auto [p, q] ();                // { dg-error "invalid initializer for 
structured binding" }

        Jakub

Reply via email to