xref: /llvm-project/clang/test/AST/ByteCode/cxx2a.cpp (revision 51c7338cc671c90ba9345b53c7ca01dc461341ed)
1 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=ref,both %s
2 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter
3 
4 template <unsigned N>
5 struct S {
6   S() requires (N==1) = default;
7   S() requires (N==2) {} // both-note {{declared here}}
8   consteval S() requires (N==3) = default;
9 };
10 
11 consteval int aConstevalFunction() { // both-error {{consteval function never produces a constant expression}}
12   S<2> s4; // both-note {{non-constexpr constructor 'S' cannot be used in a constant expression}}
13   return 0;
14 }
15 /// We're NOT calling the above function. The diagnostics should appear anyway.
16 
17 namespace Covariant {
18   struct A {
19     virtual constexpr char f() const { return 'Z'; }
20     char a = f();
21   };
22 
23   struct D : A {};
24   struct Covariant1 {
25     D d;
26     virtual const A *f() const;
27   };
28 
29   struct Covariant3 : Covariant1 {
30     constexpr virtual const D *f() const { return &this->d; }
31   };
32 
33   constexpr Covariant3 cb;
34   constexpr const Covariant1 *cb1 = &cb;
35   static_assert(cb1->f()->a == 'Z');
36 }
37 
38 namespace DtorOrder {
39   struct Buf {
40     char buf[64];
41     int n = 0;
42     constexpr void operator+=(char c) { buf[n++] = c; }
43     constexpr bool operator==(const char *str) const {
44       if (str[n] != 0)
45         return false;
46 
47       for (int i = 0; i < n; ++i) {
48         if (buf[n] != str[n])
49           return false;
50       }
51       return true;
52 
53       return __builtin_memcmp(str, buf, n) == 0;
54     }
55     constexpr bool operator!=(const char *str) const { return !operator==(str); }
56   };
57 
58   struct A {
59     constexpr A(Buf &buf, char c) : buf(buf), c(c) { buf += c; }
60     constexpr ~A() { buf += (c - 32);}
61     constexpr operator bool() const { return true; }
62     Buf &buf;
63     char c;
64   };
65 
66   constexpr void abnormal_termination(Buf &buf) {
67     struct Indestructible {
68       constexpr ~Indestructible(); // not defined
69     };
70     A a(buf, 'a');
71     A(buf, 'b');
72     int n = 0;
73 
74     for (A &&c = A(buf, 'c'); A d = A(buf, 'd'); A(buf, 'e')) {
75       switch (A f(buf, 'f'); A g = A(buf, 'g')) { // both-warning {{boolean}}
76       case false: {
77         A x(buf, 'x');
78       }
79 
80       case true: {
81         A h(buf, 'h');
82         switch (n++) {
83         case 0:
84           break;
85         case 1:
86           continue;
87         case 2:
88           return;
89         }
90         break;
91       }
92 
93       default:
94         Indestructible indest;
95       }
96 
97       A j = (A(buf, 'i'), A(buf, 'j'));
98     }
99   }
100 
101   constexpr bool check_abnormal_termination() {
102     Buf buf = {};
103     abnormal_termination(buf);
104     return buf ==
105       "abBc"
106         "dfgh" /*break*/ "HGFijIJeED"
107         "dfgh" /*continue*/ "HGFeED"
108         "dfgh" /*return*/ "HGFD"
109       "CA";
110   }
111   static_assert(check_abnormal_termination());
112 }
113 
114 namespace std {
115   struct type_info;
116 }
117 
118 namespace TypeId {
119   struct A {
120     const std::type_info &ti = typeid(*this);
121   };
122   struct A2 : A {};
123   static_assert(&A().ti == &typeid(A));
124   static_assert(&typeid((A2())) == &typeid(A2));
125   extern A2 extern_a2;
126   static_assert(&typeid(extern_a2) == &typeid(A2));
127 
128   constexpr A2 a2;
129   constexpr const A &a1 = a2;
130   static_assert(&typeid(a1) == &typeid(A));
131 
132   struct B {
133     virtual void f();
134     const std::type_info &ti1 = typeid(*this);
135   };
136   struct B2 : B {
137     const std::type_info &ti2 = typeid(*this);
138   };
139   static_assert(&B2().ti1 == &typeid(B));
140   static_assert(&B2().ti2 == &typeid(B2));
141   extern B2 extern_b2;
142   static_assert(&typeid(extern_b2) == &typeid(B2));
143 
144   constexpr B2 b2;
145   constexpr const B &b1 = b2;
146   static_assert(&typeid(b1) == &typeid(B2));
147 
148   constexpr bool side_effects() {
149     // Not polymorphic nor a glvalue.
150     bool OK = true;
151     (void)typeid(OK = false, A2()); // both-warning {{has no effect}}
152     if (!OK) return false;
153 
154     // Not polymorphic.
155     A2 a2;
156     (void)typeid(OK = false, a2); // both-warning {{has no effect}}
157     if (!OK) return false;
158 
159     // Not a glvalue.
160     (void)typeid(OK = false, B2()); // both-warning {{has no effect}}
161     if (!OK) return false;
162 
163     // Polymorphic glvalue: operand evaluated.
164     OK = false;
165     B2 b2;
166     (void)typeid(OK = true, b2); // both-warning {{will be evaluated}}
167     return OK;
168   }
169   static_assert(side_effects());
170 }
171 
172 consteval int f(int i);
173 constexpr bool test(auto i) {
174     return f(0) == 0;
175 }
176 consteval int f(int i) {
177     return 2 * i;
178 }
179 static_assert(test(42));
180