1 // P1091R3
2 // { dg-do run { target c++11 } }
3 // { dg-options "" }
4 // { dg-additional-sources decomp1-aux.cc }
5 
6 namespace std {
7   template<typename T> struct tuple_size;
8   template<int, typename> struct tuple_element;
9 }
10 
11 struct A {
12   int i;
AA13   A(int x) : i(x) {}
getA14   template <int I> int& get() { return i; }
15 };
16 struct B { int a, b, c; };
17 
18 template<> struct std::tuple_size<A> { static const int value = 2; };
19 template<int I> struct std::tuple_element<I,A> { using type = int; };
20 
21 extern int &foo (int);
22 extern int bar (int);
23 extern B s;
24 extern "C" void abort ();
25 B t = { 4, 5, 6 };
26 
27 static auto [ d, e, f ] = t;	// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
28 				// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
29 static auto [ g, h ] = A (44);	// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
30 				// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1  }
31 // The following warnings are in decomp1-aux.cc with #line directive.
32 // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 1 }
33 // { dg-warning "structured bindings only available with" "" { target c++14_down } 1 }
34 // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 2 }
35 // { dg-warning "structured bindings only available with" "" { target c++14_down } 2 }
36 // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 3 }
37 // { dg-warning "structured bindings only available with" "" { target c++14_down } 3 }
38 // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 4 }
39 // { dg-warning "structured bindings only available with" "" { target c++14_down } 4 }
40 
41 int &
42 baz (int x)
43 {
44   switch (x)
45     {
46     case 0: return d;
47     case 1: return e;
48     case 2: return f;
49     case 3: return g;
50     default: return h;
51     }
52 }
53 
54 int
55 qux (int x)
56 {
57   static auto [ m, n, o ] = t;	// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
58 				// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1  }
59   static auto [ p, q ] = A (45);	// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
60 				// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1  }
61   switch (x)
62     {
63     case 0: return ++m;
64     case 1: return ++n;
65     case 2: return ++o;
66     case 3: return ++p;
67     default: return ++q;
68     }
69 }
70 
71 int
72 main ()
73 {
74   int *a[10];
75   for (int i = 0; i < 5; ++i)
76     {
77       a[i] = &foo (i);
78       a[i + 5] = &baz (i);
79     }
80   for (int i = 0; i < 10; ++i)
81     for (int j = i + 1; j < 10; ++j)
82       if (a[i] == a[j] && (j != i + 1 || (i % 5) != 3))
83 	abort ();
84   if (a[1] != a[0] + 1 || a[2] != a[0] + 2 || a[4] != a[3]
85       || a[6] != a[5] + 1 || a[7] != a[5] + 2 || a[9] != a[8])
86     abort ();
87   int b[] = { 1, 2, 3, 43, 43 + 6, 4, 5, 6, 45, 45 + 11 };
88   for (int i = 0; i < 10; ++i)
89     for (int j = 0; j < 3 + i; ++j)
90       if ((i < 5 ? bar (i) : qux (i - 5)) != b[i] + 1 + j)
91 	abort ();
92 }
93