1 // RUN: %clang_cc1 -std=c++1z -verify -triple i686-linux-gnu %s
2 
3 template<typename T, typename U> struct same;
4 template<typename T> struct same<T, T> { ~same(); };
5 
6 struct Empty {};
7 
8 struct A {
9   int a;
10 };
11 
12 namespace NonPublicMembers {
13   struct NonPublic1 {
14   protected:
15     int a; // expected-note {{declared protected here}}
16   };
17 
18   struct NonPublic2 {
19   private:
20     int a; // expected-note 2{{declared private here}}
21   };
22 
23   struct NonPublic3 : private A {}; // expected-note {{declared private here}}
24 
25   struct NonPublic4 : NonPublic2 {};
26 
test()27   void test() {
28     auto [a1] = NonPublic1(); // expected-error {{cannot decompose protected member 'a' of 'NonPublicMembers::NonPublic1'}}
29     auto [a2] = NonPublic2(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}}
30     auto [a3] = NonPublic3(); // expected-error {{cannot decompose members of inaccessible base class 'A' of 'NonPublicMembers::NonPublic3'}}
31     auto [a4] = NonPublic4(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}}
32   }
33 }
34 
35 namespace AnonymousMember {
36   struct Struct {
37     struct { // expected-note {{declared here}}
38       int i;
39     };
40   };
41 
42   struct Union {
43     union { // expected-note {{declared here}}
44       int i;
45     };
46   };
47 
test()48   void test() {
49     auto [a1] = Struct(); // expected-error {{cannot decompose class type 'AnonymousMember::Struct' because it has an anonymous struct member}}
50     auto [a2] = Union(); // expected-error {{cannot decompose class type 'AnonymousMember::Union' because it has an anonymous union member}}
51   }
52 }
53 
54 namespace MultipleClasses {
55   struct B : A {
56     int a;
57   };
58 
59   struct C { int a; };
60   struct D : A, C {};
61 
62   struct E : virtual A {};
63   struct F : A, E {}; // expected-warning {{direct base 'A' is inaccessible due to ambiguity}}
64 
65   struct G : virtual A {};
66   struct H : E, G {};
67 
68   struct I { int i; };
69   struct J : I {};
70   struct K : I, virtual J {}; // expected-warning {{direct base 'MultipleClasses::I' is inaccessible due to ambiguity}}
71 
72   struct L : virtual J {};
73   struct M : virtual J, L {};
74 
test()75   void test() {
76     auto [b] = B(); // expected-error {{cannot decompose class type 'B': both it and its base class 'A' have non-static data members}}
77     auto [d] = D(); // expected-error {{cannot decompose class type 'D': its base classes 'A' and 'MultipleClasses::C' have non-static data members}}
78     auto [e] = E();
79     auto [f] = F(); // expected-error-re {{cannot decompose members of ambiguous base class 'A' of 'F':{{.*}}struct MultipleClasses::F -> struct A{{.*}}struct MultipleClasses::F -> struct MultipleClasses::E -> struct A}}
80     auto [h] = H(); // ok, only one (virtual) base subobject even though there are two paths to it
81     auto [k] = K(); // expected-error {{cannot decompose members of ambiguous base class 'MultipleClasses::I'}}
82     auto [m] = M(); // ok, all paths to I are through the same virtual base subobject J
83 
84     same<decltype(m), int>();
85   }
86 }
87 
88 namespace BindingTypes {
89   struct A {
90     int i = 0;
91     int &r = i;
92     const float f = i;
93     mutable volatile int mvi;
94   };
e()95   void e() {
96     auto [i,r,f,mvi] = A();
97 
98     same<decltype(i), int>();
99     same<decltype(r), int&>();
100     same<decltype(f), const float>();
101     same<decltype(mvi), volatile int>();
102 
103     same<decltype((i)), int&>();
104     same<decltype((r)), int&>();
105     same<decltype((f)), const float&>();
106     same<decltype((mvi)), volatile int&>();
107   }
f()108   void f() {
109     auto &&[i,r,f,mvi] = A();
110 
111     same<decltype(i), int>();
112     same<decltype(r), int&>();
113     same<decltype(f), const float>();
114     same<decltype(mvi), volatile int>();
115 
116     same<decltype((i)), int&>();
117     same<decltype((r)), int&>();
118     same<decltype((f)), const float&>();
119     same<decltype((mvi)), volatile int&>();
120   }
g()121   void g() {
122     const auto [i,r,f,mvi] = A();
123 
124     same<decltype(i), const int>();
125     same<decltype(r), int&>();
126     same<decltype(f), const float>();
127     same<decltype(mvi), volatile int>(); // not 'const volatile int', per expected resolution of DRxxx
128 
129     same<decltype((i)), const int&>();
130     same<decltype((r)), int&>();
131     same<decltype((f)), const float&>();
132     same<decltype((mvi)), volatile int&>(); // not 'const volatile int&', per expected resolution of DRxxx
133   }
h()134   void h() {
135     typedef const A CA;
136     auto &[i,r,f,mvi] = CA(); // type of var is 'const A &'
137 
138     same<decltype(i), const int>(); // not 'int', per expected resolution of DRxxx
139     same<decltype(r), int&>();
140     same<decltype(f), const float>();
141     same<decltype(mvi), volatile int>(); // not 'const volatile int', per expected resolution of DRxxx
142 
143     same<decltype((i)), const int&>(); // not 'int&', per expected resolution of DRxxx
144     same<decltype((r)), int&>();
145     same<decltype((f)), const float&>();
146     same<decltype((mvi)), volatile int&>(); // not 'const volatile int&', per expected resolution of DRxxx
147   }
148   struct B {
149     mutable int i;
150   };
mut()151   void mut() {
152     auto [i] = B();
153     const auto [ci] = B();
154     volatile auto [vi] = B();
155     same<decltype(i), int>();
156     same<decltype(ci), int>();
157     same<decltype(vi), volatile int>();
158   }
159 }
160 
161 namespace Bitfield {
162   struct S { unsigned long long x : 4, y : 32; int z; }; // expected-note 2{{here}}
f(S s)163   int f(S s) {
164     auto [a, b, c] = s;
165     unsigned long long &ra = a; // expected-error {{bit-field 'x'}}
166     unsigned long long &rb = b; // expected-error {{bit-field 'y'}}
167     int &rc = c;
168 
169     // the type of the binding is the type of the field
170     same<decltype(a), unsigned long long>();
171     same<decltype(b), unsigned long long>();
172 
173     // the type of the expression is an lvalue of the field type
174     // (even though a reference can't bind to the field)
175     same<decltype((a)), unsigned long long&>();
176     same<decltype((b)), unsigned long long&>();
177 
178     // the expression promotes to a type large enough to hold the result
179     same<decltype(+a), int>();
180     same<decltype(+b), unsigned int>();
181     return rc;
182   }
183 }
184 
185 namespace Constexpr {
QConstexpr::Q186   struct Q { int a, b; constexpr Q() : a(1), b(2) {} };
187   constexpr Q q;
188   auto &[qa, qb] = q;
189   static_assert(&qa == &q.a && &qb == &q.b);
190   static_assert(qa == 1 && qb == 2);
191 }
192 
193 namespace std_example {
194   struct S { int x1 : 2; volatile double y1; };
195   S f();
196   const auto [x, y] = f();
197 
198   same<decltype((x)), const int&> same1;
199   same<decltype((y)), const volatile double&> same2;
200 }
201 
202 namespace p0969r0 {
203   struct A {
204     int x;
205     int y;
206   };
207   struct B : private A { // expected-note {{declared private here}}
test_memberp0969r0::B208     void test_member() {
209       auto &[x, y] = *this;
210     }
211     friend void test_friend(B);
212   };
test_friend(B b)213   void test_friend(B b) {
214     auto &[x, y] = b;
215   }
test_external(B b)216   void test_external(B b) {
217     auto &[x, y] = b; // expected-error {{cannot decompose members of inaccessible base class 'p0969r0::A' of 'p0969r0::B'}}
218   }
219 
220   struct C {
221     int x;
222   protected:
223     int y; // expected-note {{declared protected here}} expected-note {{can only access this member on an object of type 'p0969r0::D'}}
test_memberp0969r0::C224     void test_member() {
225       auto &[x, y] = *this;
226     }
227     friend void test_friend(struct D);
228   };
229   struct D : C {
test_memberp0969r0::D230     static void test_member(D d, C c) {
231       auto &[x1, y1] = d;
232       auto &[x2, y2] = c; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}}
233     }
234   };
test_friend(D d)235   void test_friend(D d) {
236     auto &[x, y] = d;
237   }
test_external(D d)238   void test_external(D d) {
239     auto &[x, y] = d; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}}
240   }
241 }
242