On Tue, Jan 10, 2017 at 02:03:14PM -0500, Jason Merrill wrote:
> The FI20 comment on the decomposition declarations proposal complained
> that the syntax unnecessarily excluded parenthesized initialization.
> This patch implements the resolution.
> 
> Tested x86_64-pc-linux-gnu, applying to trunk.

> commit 749ec367e50b356a40fd41a3daae10d9d948062b
> Author: Jason Merrill <ja...@redhat.com>
> Date:   Mon Jan 9 17:33:42 2017 -0500
> 
>             FI 20, decomposition declaration with parenthesized initializer.
>
>             * parser.c (cp_parser_decomposition_declaration): Use
>             cp_parser_initializer.

I had a testcase for this from the time when I've been trying to implement
FI 20 myself.  Here is just the testcase change, but it fails,
instead of invoking the explicit A (const A &x) ctor I was expecting
for auto [b,c,d,e,f,g] ( a );, that is the ctor invoked also for
auto [b,c,d,e,f,g] { a };, it is invoking the
template <typename T> A (const T &x) ctor that is invoked for
auto [b,c,d,e,f,g] = a;
So, is auto [b,c,d,e,f,g] ( a ); direct initialization like
auto [b,c,d,e,f,g] { a }; or is it copy initialization like
auto [b,c,d,e,f,g] = a; ?
Note, I've tried to compile the decomp6.C testcase (and all other decomp*
testcases) with svn trunk clang++ too, and it fails on the
      auto [b,c,d,e,f,g] { a };
on line 62 already:
decomp6.C:12:24: error: member reference base type 'A const[6]' is not a 
structure or union
  A (const T &x) : a (x.a) { tccnt++; }
                      ~^~
decomp6.C:62:28: note: in instantiation of function template specialization 
'A::A<A [6]>' requested here
      auto [b,c,d,e,f,g] { a };         // { dg-warning "decomposition 
declaration only available with" "" { target c++14_down } }
                           ^
Is that a clang++ bug, right?  That said, when I change that line 62 to:
auto [b,c,d,e,f,g] ( a );, the test passes with clang++ even when patched
with the patch, so (a) seems to be treated as direct-initialization.
clang++ ICEd on a bunch of testcases, but when it didn't, appart from decomp6.C
matched my expectations on where errors should be reported and where not.

Lastly, I have a testcase I'm not sure about:
int a[3];
struct S { int b, c, d; } s;
void
foo ()
{
  auto [ b, c, d ] = a;
  auto [ e, f, g ] = s;
  auto [ h, i, j ] { s };
  auto [ k, l, m ] { s, };
  auto [ n, o, p ] { a };       // { dg-error "invalid conversion from 'int.' 
to 'int'" }
  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 }
}
but where clang++ actually matches the current g++ behavior.
In the
https://github.com/cplusplus/draft/commit/6f3920a66311ec2893a9e30ce2b54cecba4951ba
wording, it talks only about assignment-expression in between () or {}, does
that mean:
auto [ k, l, m ] { s, };
should be invalid?  And is the auto [ n, o, p ] { a }; error a bug or not
(though clang++ agrees on that with g++).  We don't error on
auto [ x, y, z ] ( a );

2017-01-11  Jakub Jelinek  <ja...@redhat.com>

        FI 20, decomposition declaration with parenthesized initializer.
        * g++.dg/cpp1z/decomp6.C (main): Add further tests.

--- gcc/testsuite/g++.dg/cpp1z/decomp6.C.jj     2016-11-14 08:52:27.000000000 
+0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp6.C        2016-11-29 18:11:33.000000000 
+0100
@@ -89,4 +89,40 @@ main ()
   }
   if (ccnt != 12 || dcnt != 24 || cccnt != 6 || tccnt != 6)
     __builtin_abort ();
+
+  {
+    A a[6];
+    if (ccnt != 18 || dcnt != 24 || cccnt != 6 || tccnt != 6)
+      __builtin_abort ();
+    {
+      auto [b,c,d,e,f,g] ( a );                // { dg-warning "decomposition 
declaration only available with" "" { target c++14_down } }
+      if (ccnt != 18 || dcnt != 24 || cccnt != 12 || tccnt != 6)
+       __builtin_abort ();
+      b.a++;
+      c.a += 2;
+      f.a += 3;
+      if (b.a != 7 || c.a != 8 || d.a != 6 || e.a != 6 || f.a != 9 || g.a != 6)
+       __builtin_abort ();
+      if (&b == &a[0] || &c == &a[1] || &d == &a[2] || &e == &a[3] || &f == 
&a[4] || &g == &a[5])
+       __builtin_abort ();
+      {
+       auto&[ h, i, j, k, l, m ] (a);  // { dg-warning "decomposition 
declaration only available with" "" { target c++14_down } }
+       if (ccnt != 18 || dcnt != 24 || cccnt != 12 || tccnt != 6)
+         __builtin_abort ();
+       j.a += 4;
+       k.a += 5;
+       m.a += 6;
+       if (a[0].a != 6 || a[1].a != 6 || a[2].a != 10 || a[3].a != 11 || 
a[4].a != 6 || a[5].a != 12)
+         __builtin_abort ();
+       if (&h != &a[0] || &i != &a[1] || &j != &a[2] || &k != &a[3] || &l != 
&a[4] || &m != &a[5])
+         __builtin_abort ();
+      }
+      if (ccnt != 18 || dcnt != 24 || cccnt != 12 || tccnt != 6)
+       __builtin_abort ();
+    }
+    if (ccnt != 18 || dcnt != 30 || cccnt != 12 || tccnt != 6)
+      __builtin_abort ();
+  }
+  if (ccnt != 18 || dcnt != 36 || cccnt != 12 || tccnt != 6)
+    __builtin_abort ();
 }


        Jakub

Reply via email to