Richard Smith | 24ad121 | 2020-02-18 16:13:23 -0800 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,pedantic,override,reorder -pedantic-errors |
| 2 | // RUN: %clang_cc1 -std=c++17 %s -verify=expected,pedantic,override,reorder -Wno-c++20-designator -pedantic-errors |
| 3 | // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,pedantic -Werror=c99-designator -Wno-reorder-init-list -Wno-initializer-overrides |
| 4 | // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,reorder -Wno-c99-designator -Werror=reorder-init-list -Wno-initializer-overrides |
| 5 | // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,override -Wno-c99-designator -Wno-reorder-init-list -Werror=initializer-overrides |
| 6 | // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides |
Richard Smith | 5030928 | 2019-08-30 22:52:55 +0000 | [diff] [blame] | 7 | |
Richard Smith | 79c88c3 | 2018-09-26 19:00:16 +0000 | [diff] [blame] | 8 | |
| 9 | namespace class_with_ctor { |
Richard Smith | ea36612 | 2019-09-02 23:27:54 +0000 | [diff] [blame] | 10 | struct A { // cxx20-note 6{{candidate}} |
| 11 | A() = default; // cxx20-note 3{{candidate}} |
Richard Smith | 79c88c3 | 2018-09-26 19:00:16 +0000 | [diff] [blame] | 12 | int x; |
| 13 | int y; |
| 14 | }; |
Richard Smith | ea36612 | 2019-09-02 23:27:54 +0000 | [diff] [blame] | 15 | A a = {1, 2}; // cxx20-error {{no matching constructor}} |
Richard Smith | 79c88c3 | 2018-09-26 19:00:16 +0000 | [diff] [blame] | 16 | |
| 17 | struct B { |
| 18 | int x; |
| 19 | int y; |
| 20 | }; |
| 21 | B b1 = B(); // trigger declaration of implicit ctors |
| 22 | B b2 = {1, 2}; // ok |
| 23 | |
| 24 | struct C : A { |
| 25 | A a; |
| 26 | }; |
| 27 | C c1 = {{}, {}}; // ok, call default ctor twice |
Richard Smith | ea36612 | 2019-09-02 23:27:54 +0000 | [diff] [blame] | 28 | C c2 = {{1, 2}, {3, 4}}; // cxx20-error 2{{no matching constructor}} |
Richard Smith | 79c88c3 | 2018-09-26 19:00:16 +0000 | [diff] [blame] | 29 | } |
Richard Smith | 5030928 | 2019-08-30 22:52:55 +0000 | [diff] [blame] | 30 | |
| 31 | namespace designator { |
| 32 | struct A { int x, y; }; |
| 33 | struct B { A a; }; |
| 34 | |
| 35 | A a1 = { |
| 36 | .y = 1, // reorder-note {{previous initialization for field 'y' is here}} |
| 37 | .x = 2 // reorder-error {{ISO C++ requires field designators to be specified in declaration order; field 'y' will be initialized after field 'x'}} |
| 38 | }; |
| 39 | int arr[3] = {[1] = 5}; // pedantic-error {{array designators are a C99 extension}} |
| 40 | B b = {.a.x = 0}; // pedantic-error {{nested designators are a C99 extension}} |
| 41 | A a2 = { |
| 42 | .x = 1, // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}} |
| 43 | 2 // pedantic-note {{first non-designated initializer is here}} |
| 44 | }; |
| 45 | A a3 = { |
| 46 | 1, // pedantic-note {{first non-designated initializer is here}} |
| 47 | .y = 2 // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}} |
| 48 | }; |
| 49 | A a4 = { |
| 50 | .x = 1, // override-note {{previous}} |
| 51 | .x = 1 // override-error {{overrides prior initialization}} |
| 52 | }; |
| 53 | A a5 = { |
| 54 | .y = 1, // override-note {{previous}} |
| 55 | .y = 1 // override-error {{overrides prior initialization}} |
| 56 | }; |
| 57 | struct C { int :0, x, :0, y, :0; }; |
| 58 | C c = { |
| 59 | .x = 1, // override-note {{previous}} |
| 60 | .x = 1, // override-error {{overrides prior initialization}} override-note {{previous}} |
| 61 | .y = 1, // override-note {{previous}} |
| 62 | .y = 1, // override-error {{overrides prior initialization}} |
| 63 | .x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}} |
| 64 | .x = 1, // override-error {{overrides prior initialization}} |
| 65 | }; |
| 66 | } |
| 67 | |
| 68 | namespace base_class { |
| 69 | struct base { |
| 70 | int x; |
| 71 | }; |
| 72 | struct derived : base { |
| 73 | int y; |
| 74 | }; |
| 75 | derived d = {.x = 1, .y = 2}; // expected-error {{'x' does not refer to any field}} |
| 76 | } |
| 77 | |
| 78 | namespace union_ { |
| 79 | union U { int a, b; }; |
| 80 | U u = { |
| 81 | .a = 1, // override-note {{here}} |
| 82 | .b = 2, // override-error {{overrides prior}} |
| 83 | }; |
| 84 | } |
| 85 | |
| 86 | namespace overload_resolution { |
| 87 | struct A { int x, y; }; |
| 88 | union B { int x, y; }; |
| 89 | |
| 90 | void f(A a); |
| 91 | void f(B b) = delete; |
| 92 | void g() { f({.x = 1, .y = 2}); } // ok, calls non-union overload |
| 93 | |
| 94 | // As an extension of the union case, overload resolution won't pick any |
| 95 | // candidate where a field initializer would be overridden. |
| 96 | struct A2 { int x, other, y; }; |
| 97 | int f(A2); |
| 98 | void g2() { int k = f({.x = 1, 2, .y = 3}); (void)k; } // pedantic-error {{mixture of designated and non-designated}} pedantic-note {{here}} |
| 99 | |
| 100 | struct C { int x; }; |
| 101 | void h(A a); // expected-note {{candidate}} |
| 102 | void h(C c); // expected-note {{candidate}} |
| 103 | void i() { |
| 104 | h({.x = 1, .y = 2}); |
| 105 | h({.y = 1, .x = 2}); // reorder-error {{declaration order}} reorder-note {{previous}} |
| 106 | h({.x = 1}); // expected-error {{ambiguous}} |
| 107 | } |
| 108 | |
| 109 | struct D { int y, x; }; |
| 110 | void j(A a); // expected-note {{candidate}} |
| 111 | void j(D d); // expected-note {{candidate}} |
| 112 | void k() { |
| 113 | j({.x = 1, .y = 2}); // expected-error {{ambiguous}} |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | namespace deduction { |
| 118 | struct A { int x, y; }; |
| 119 | union B { int x, y; }; |
| 120 | |
| 121 | template<typename T, typename U> void f(decltype(T{.x = 1, .y = 2}) = {}); |
| 122 | template<typename T, typename U> void f(decltype(U{.x = 1, .y = 2}) = {}) = delete; |
| 123 | void g() { f<A, B>(); } // ok, calls non-union overload |
| 124 | |
| 125 | struct C { int y, x; }; |
| 126 | template<typename T, typename U> void h(decltype(T{.y = 1, .x = 2}) = {}) = delete; |
| 127 | template<typename T, typename U> void h(decltype(U{.y = 1, .x = 2}) = {}); |
| 128 | void i() { |
| 129 | h<A, C>(); // ok, selects C overload by SFINAE |
| 130 | } |
| 131 | } |