Here, we had DECL_VALUE_EXPR of a structured binding referring to a
pass-by-invisible-reference parameter, but not being adjusted by
cp_genericize.  We get here because we were looking through a
reference temporary.  Removing that code doesn't seem to break
anything; I'm guessing that it isn't needed anymore because of my
change to support references better in constexpr evaluation.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 793633ca2cbbcd2ba9175320728745d6ebcba9e8
Author: Jason Merrill <ja...@redhat.com>
Date:   Sat Mar 18 23:47:50 2017 -0400

            PR c++/80084 - wrong C++17 decomposition by reference of parameter.
    
            * decl.c (cp_finish_decomp): Don't pull out the DECL_INITIAL of a
            reference decomposition.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index bf24e8b..0a92566 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7439,9 +7439,6 @@ cp_finish_decomp (tree decl, tree first, unsigned int 
count)
 
   if (TREE_CODE (type) == REFERENCE_TYPE)
     {
-      /* If e is a constant reference, use the referent directly.  */
-      if (DECL_INITIAL (decl))
-       dexp = DECL_INITIAL (decl);
       dexp = convert_from_reference (dexp);
       type = TREE_TYPE (type);
     }
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp27.C 
b/gcc/testsuite/g++.dg/cpp1z/decomp27.C
new file mode 100644
index 0000000..f26722a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp27.C
@@ -0,0 +1,26 @@
+// PR c++/80084
+// { dg-options -std=c++1z }
+// { dg-do run }
+
+struct A
+{
+  A() { }
+  A(const A&) { }
+};
+
+struct B
+{
+  A a;
+};
+
+void f(B b)
+{
+  auto& [a] = b;
+  if (&a != &b.a)
+    __builtin_abort();
+}
+
+int main()
+{
+  f(B());
+}

Reply via email to