Clang Project

clang_source_code/test/CXX/dcl.decl/dcl.decomp/p4.cpp
1// RUN: %clang_cc1 -std=c++1z -verify -triple i686-linux-gnu %s
2
3template<typename T, typename U> struct same;
4template<typename T> struct same<T, T> { ~same(); };
5
6struct Empty {};
7
8struct A {
9  int a;
10};
11
12namespace 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
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
35namespace 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
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
54namespace 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
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
88namespace BindingTypes {
89  struct A {
90    int i = 0;
91    int &r = i;
92    const float f = i;
93    mutable volatile int mvi;
94  };
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  }
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  }
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  }
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  };
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
161namespace Bitfield {
162  struct S { unsigned long long x : 4, y : 32; int z; }; // expected-note 2{{here}}
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
185namespace Constexpr {
186  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
193namespace 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
202namespace p0969r0 {
203  struct A {
204    int x;
205    int y;
206  };
207  struct B : private A { // expected-note {{declared private here}}
208    void test_member() {
209      auto &[x, y] = *this;
210    }
211    friend void test_friend(B);
212  };
213  void test_friend(B b) {
214    auto &[x, y] = b;
215  }
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'}}
224    void test_member() {
225      auto &[x, y] = *this;
226    }
227    friend void test_friend(struct D);
228  };
229  struct D : C {
230    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  };
235  void test_friend(D d) {
236    auto &[x, y] = d;
237  }
238  void test_external(D d) {
239    auto &[x, y] = d; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}}
240  }
241}
242