From de3d4fd0f5439fcc8e3ae10d9f439c007dfacb1d Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Mon, 27 Nov 2017 22:54:25 +0100
Subject: [PATCH] re PR c++/81888 (Structured bindings stopped working)

	PR c++/81888
	* parser.c (cp_parser_decomposition_declaration): Reject just
	BRACE_ENCLOSED_INITIALIZER_P initializers with nelts != 1 rather
	than all such CONSTRUCTORs, and only if is_direct_init is true.

	* g++.dg/cpp1z/decomp30.C: Add a test for structured binding with
	= {} and = { a, a } initializers.
	* g++.dg/cpp1z/decomp31.C: New test.

From-SVN: r255180
---
 gcc/cp/ChangeLog                      |  7 +++++++
 gcc/cp/parser.c                       |  3 ++-
 gcc/testsuite/ChangeLog               |  7 +++++++
 gcc/testsuite/g++.dg/cpp1z/decomp30.C |  2 ++
 gcc/testsuite/g++.dg/cpp1z/decomp31.C | 18 ++++++++++++++++++
 5 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp31.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 91de626f9100..a5735eb71a65 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/81888
+	* parser.c (cp_parser_decomposition_declaration): Reject just
+	BRACE_ENCLOSED_INITIALIZER_P initializers with nelts != 1 rather
+	than all such CONSTRUCTORs, and only if is_direct_init is true.
+
 2017-11-27  Jason Merrill  <jason@redhat.com>
 
 	* pt.c (primary_template_specialization_p): Rename from
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 847ad1464e1b..eae73fcab2fd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -13382,7 +13382,8 @@ cp_parser_decomposition_declaration (cp_parser *parser,
       if (initializer == NULL_TREE
 	  || (TREE_CODE (initializer) == TREE_LIST
 	      && TREE_CHAIN (initializer))
-	  || (TREE_CODE (initializer) == CONSTRUCTOR
+	  || (is_direct_init
+	      && BRACE_ENCLOSED_INITIALIZER_P (initializer)
 	      && CONSTRUCTOR_NELTS (initializer) != 1))
 	{
 	  error_at (loc, "invalid initializer for structured binding "
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bfcf7b19cdc8..8203f5c0590d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/81888
+	* g++.dg/cpp1z/decomp30.C: Add a test for structured binding with
+	= {} and = { a, a } initializers.
+	* g++.dg/cpp1z/decomp31.C: New test.
+
 2017-11-27  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
 	PR middle_end/82333
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp30.C b/gcc/testsuite/g++.dg/cpp1z/decomp30.C
index 73068712d5f5..b11a3127777a 100644
--- a/gcc/testsuite/g++.dg/cpp1z/decomp30.C
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp30.C
@@ -10,3 +10,5 @@ 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 declaration" }
 auto [p, q] ();		// { dg-error "invalid initializer for structured binding declaration" }
+auto [r, s] = {};	// { dg-error "deducing from brace-enclosed initializer list requires" }
+auto [t, u] = { a, a };	// { dg-error "deducing from brace-enclosed initializer list requires" }
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp31.C b/gcc/testsuite/g++.dg/cpp1z/decomp31.C
new file mode 100644
index 000000000000..ebc44b435890
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp31.C
@@ -0,0 +1,18 @@
+// PR c++/81888
+// { dg-do compile { target c++17 } }
+
+struct S {
+  bool s = true;
+};
+
+auto [a] = S{};
+
+template <class T>
+bool
+foo () noexcept
+{
+  auto [c] = T{};
+  return c;
+}
+
+const bool b = foo<S> ();
-- 
GitLab