[C++] Fix decomp ICE with invalid initializer (PR c++/81258)

Jakub Jelinek jakub@redhat.com
Fri Jun 30 17:24:00 GMT 2017


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  <jakub@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



More information about the Gcc-patches mailing list