428 lines · cpp
1// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only2// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only -fexperimental-new-constant-interpreter3// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only -fexperimental-new-constant-interpreter4// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only5 6struct A { // expected-note 4{{candidate constructor}}7 char i;8 double j;9};10 11struct B {12 A a;13 int b[20];14 int &&c;15};16 17struct C { // expected-note 5{{candidate constructor}}18 A a;19 int b[20];20};21 22struct D : public C, public A {23 int a;24};25 26struct E {27 struct F { // expected-note 2{{candidate constructor}}28 F(int, int); // expected-note {{candidate constructor}}29 };30 int a;31 F f;32};33 34int getint(); // expected-note {{declared here}}35 36struct F {37 int a;38 int b = getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}}39};40 41template <typename T>42struct G {43 T t1;44 T t2;45};46 47struct H {48 virtual void foo() = 0;49};50 51struct I : public H { // expected-note 3{{candidate constructor}}52 int i, j;53 void foo() override {}54};55 56struct J {57 int a;58 int b[]; // expected-note {{initialized flexible array member 'b' is here}}59};60 61enum K { K0, K1, K2 };62 63struct L {64 K k : 1;65};66 67struct M {68 struct N {69 private:70 N(int);71 // expected-note@-1 {{declared private here}}72 };73 int i;74 N n;75};76 77union U {78 int a;79 char* b;80};81 82template <typename T, char CH>83void bar() {84 T t = 0;85 A a(CH, 1.1); // OK; C++ paren list constructors are supported in semantic tree transformations.86 // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}87}88 89template <class T, class... Args>90T Construct(Args... args) {91 return T(args...); // OK; variadic arguments can be used in paren list initializers.92 // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}93}94 95void foo(int n) { // expected-note {{declared here}}96 A a1(1954, 9, 21);97 // expected-error@-1 {{excess elements in struct initializer}}98 A a2(2.1);99 // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}100 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}101 A a3(-1.2, 9.8);102 // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}103 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}104 A a4 = static_cast<A>(1.1);105 // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}106 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}107 A a5 = (A)3.1;108 // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}109 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}110 A a6 = A(8.7);111 // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}112 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}113 114 B b1(2022, {7, 8});115 // expected-error@-1 {{no viable conversion from 'int' to 'A'}}116 B b2(A(1), {}, 1);117 // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}118 // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}119 // expected-warning@-3 {{temporary whose address is used as value of local variable 'b2' will be destroyed at the end of the full-expression}}120 121 C c(A(1), 1, 2, 3, 4);122 // expected-error@-1 {{array initializer must be an initializer list}}123 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}124 D d1(1);125 // expected-error@-1 {{no viable conversion from 'int' to 'C'}}126 D d2(C(1));127 // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}}128 // beforecxx20-warning@-2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}}129 D d3(C(A(1)), 1);130 // expected-error@-1 {{no viable conversion from 'int' to 'A'}}131 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}132 // beforecxx20-warning@-3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}}133 134 int arr1[](0, 1, 2, A(1));135 // expected-error@-1 {{no viable conversion from 'A' to 'int'}}136 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}137 138 int arr2[2](0, 1, 2);139 // expected-error@-1 {{excess elements in array initializer}}140 141 // We should not build paren list initilizations for IK_COPY.142 int arr3[1] = 1;143 // expected-error@-1 {{array initializer must be an initializer list}}144 145 U u1("abcd");146 // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}147 U u2(1, "efgh");148 // expected-error@-1 {{excess elements in union initializer}}149 150 E e1(1);151 // expected-error@-1 {{no matching constructor for initialization of 'F'}}152 153 constexpr F f1(1);154 // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}155 // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}156 157 constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression.158 // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}159 160 G<char> g('b', 'b');161 // beforecxx20-warning@-1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}}162 163 A a7 = Construct<A>('i', 2.2);164 // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct<A, char, double>' requested here}}165 166 L l(K::K2);167 // expected-warning@-1 {{implicit truncation}}168 // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}169 170 int arr4[](1, 2);171 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}172 173 int arr5[2](1, 2);174 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}175 176 int arr6[n](1, 2, 3); // expected-warning {{variable length arrays in C++ are a Clang extension}} \177 expected-note {{function parameter 'n' with unknown value cannot be used in a constant expression}} \178 expected-error {{variable-sized object may not be initialized}}179 180 I i(1, 2);181 // expected-error@-1 {{no matching constructor for initialization of 'I'}}182 183 J j(1, {2, 3});184 // expected-error@-1 {{initialization of flexible array member is not allowed}}185 186 M m(1, 1);187 // expected-error@-1 {{field of type 'N' has private constructor}}188 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}189 190 static_assert(__is_trivially_constructible(A, char, double));191 static_assert(__is_trivially_constructible(A, char, int));192 static_assert(__is_trivially_constructible(A, char));193 194 static_assert(__is_trivially_constructible(D, C, A, int));195 static_assert(__is_trivially_constructible(D, C));196 197 static_assert(__is_trivially_constructible(int[2], int, int));198 static_assert(__is_trivially_constructible(int[2], int, double));199 static_assert(__is_trivially_constructible(int[2], int));200}201 202namespace gh59675 {203struct K {204 template <typename T>205 K(T);206 207 virtual ~K();208};209 210union V {211 K k;212 // expected-note@-1 {{default constructor of 'V' is implicitly deleted because field 'k' has no default constructor}}213 // expected-note@-2 2{{copy constructor of 'V' is implicitly deleted because variant field 'k' has a non-trivial copy constructor}}214};215 216static_assert(!__is_constructible(V, const V&));217static_assert(!__is_constructible(V, V&&));218 219void bar() {220 V v1;221 // expected-error@-1 {{call to implicitly-deleted default constructor of 'V'}}222 223 V v2(v1);224 // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}225 226 V v3((V&&) v1);227 // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}228}229}230 231namespace gh62296 {232struct L {233protected:234 L(int);235 // expected-note@-1 2{{declared protected here}}236};237 238struct M : L {};239 240struct N {241 L l;242};243 244M m(42);245// expected-error@-1 {{base class 'L' has protected constructor}}246// beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}247 248N n(43);249// expected-error@-1 {{field of type 'L' has protected constructor}}250// beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}251}252 253namespace gh61567 {254struct O {255 int i;256 int &&j;257 // expected-note@-1 {{uninitialized reference member is here}}258 int &&k = 1;259};260 261O o1(0, 0, 0); // no-error262// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}263// expected-warning@-2 {{temporary whose address is used as value of local variable 'o1' will be destroyed at the end of the full-expression}}264// expected-warning@-3 {{temporary whose address is used as value of local variable 'o1' will be destroyed at the end of the full-expression}}265 266O o2(0, 0); // no-error267// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}268// expected-warning@-2 {{temporary whose address is used as value of local variable 'o2' will be destroyed at the end of the full-expression}}269 270O o3(0);271// expected-error@-1 {{reference member of type 'int &&' uninitialized}}272}273 274namespace gh63008 {275auto a = new A('a', {1.1});276// expected-warning@-1 {{braces around scalar init}}277// beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}278}279 280 281namespace GH63278 {282struct S {283 int a = 0;284 int b {0};285 auto x = 1; // expected-error {{'auto' not allowed in non-static struct member}}286 static const auto y = 1;287};288 289int test() {290 // used to crash291 S a(0, 1);292 S b(0);293 S c(0, 0, 1);294 295 S d {0, 1};296 S e {0};297 S f {0, 0, 1};298}299 300}301 302namespace gh63758 {303 struct S {} s;304 auto words = (char[])s; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}}305};306 307namespace GH63903 {308 constexpr int f(); // expected-note {{declared here}}309 struct S {310 int a = 0, b = f(); // expected-note {{undefined function 'f' cannot be used in a constant expression}}311 };312 313 // Test that errors produced by default members are produced at the location of the initialization314 constexpr S s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \315 // expected-error {{constexpr variable 's' must be initialized by a constant expression}}316}317 318namespace gh62863 {319 320int (&&arr)[] = static_cast<int[]>(42);321// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}322int (&&arr1)[1] = static_cast<int[]>(42);323// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}324int (&&arr2)[2] = static_cast<int[]>(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}}325// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}326int (&&arr3)[3] = static_cast<int[3]>(42);327// beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}328 329int (&&arr4)[] = (int[])(42);330// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}331int (&&arr5)[1] = (int[])(42);332// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}333int (&&arr6)[2] = (int[])(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}}334// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}335int (&&arr7)[3] = (int[3])(42);336// beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}337 338}339 340namespace GH92284 {341 342using T = int[1]; T x(42);343// beforecxx20-warning@-1 {{aggregate initialization of type 'T' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}}344using Ta = int[2]; Ta a(42);345// beforecxx20-warning@-1 {{aggregate initialization of type 'Ta' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}}346using Tb = int[2]; Tb b(42,43);347// beforecxx20-warning@-1 {{aggregate initialization of type 'Tb' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}}348using Tc = int[]; Tc c(42);349// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}350using Td = int[]; Td d(42,43);351// beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}352template<typename T, int Sz> using ThroughAlias = T[Sz];353ThroughAlias<int, 1> e(42);354// beforecxx20-warning@-1 {{aggregate initialization of type 'ThroughAlias<int, 1>' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}}355 356}357 358namespace CXXParenListInitExpr {359 360struct S {361 int a, b;362 bool flag = false;363 364 constexpr bool operator==(S rhs) {365 return a == rhs.a && b == rhs.b;366 }367};368 369static_assert(S(1, 2) == S(1, 2)); // beforecxx20-warning 2{{C++20 extension}}370 371static_assert(S(1, 2) == S(3, 4));372// expected-error@-1 {{failed due to requirement 'CXXParenListInitExpr::S(1, 2) == CXXParenListInitExpr::S(3, 4)'}} \373// beforecxx20-warning@-1 2{{C++20 extension}}374 375}376 377namespace GH72880 {378struct Base {};379struct Derived : Base {380 int count = 42;381};382 383template <typename T>384struct BaseTpl {};385template <typename T>386struct DerivedTpl : BaseTpl<T> {387 int count = 43;388};389template <typename T> struct S {390 void f() {391 Derived a = static_cast<Derived>(Base());392 // beforecxx20-warning@-1 {{C++20 extension}}393 DerivedTpl b = static_cast<DerivedTpl<T>>(BaseTpl<T>());394 // beforecxx20-warning@-1 {{C++20 extension}}395 static_assert(static_cast<Derived>(Base()).count == 42);396 // beforecxx20-warning@-1 {{C++20 extension}}397 static_assert(static_cast<DerivedTpl<T>>(BaseTpl<T>()).count == 43);398 // beforecxx20-warning@-1 {{C++20 extension}}399 }400};401 402void test() {403 S<int>{}.f(); // beforecxx20-note {{requested here}}404}405}406 407namespace GH72880_regression {408struct E {409 int i = 42;410};411struct G {412 E e;413};414template <typename>415struct Test {416 void f() {417 constexpr E e;418 //FIXME: We should only warn one419 constexpr G g(e); // beforecxx20-warning 2{{C++20 extension}}420 static_assert(g.e.i == 42);421 }422};423void test() {424 Test<int>{}.f(); // beforecxx20-note {{requested here}}425}426 427}428