1 // RUN: %clang_cc1 -std=c++11 -verify %s -pedantic 2 // RUN: %clang_cc1 -std=c++11 -verify %s -pedantic -fexperimental-new-constant-interpreter 3 // RUN: %clang_cc1 -std=c++20 -verify %s -pedantic 4 // RUN: %clang_cc1 -std=c++20 -verify %s -pedantic -fexperimental-new-constant-interpreter 5 6 7 namespace PR31692 { 8 struct A { 9 struct X { int n = 0; } x; 10 // Trigger construction of X() from a SFINAE context. This must not mark 11 // any part of X as invalid. 12 static_assert(!__is_constructible(X), ""); 13 // Check that X::n is not marked invalid. 14 double &r = x.n; // expected-error {{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}} 15 }; 16 // A::X can now be default-constructed. 17 static_assert(__is_constructible(A::X), ""); 18 } 19 20 21 struct S { 22 } constexpr s; 23 struct C { 24 C(S); 25 }; 26 class MemInit { 27 C m = s; 28 }; 29 30 namespace std { 31 typedef decltype(sizeof(int)) size_t; 32 33 // libc++'s implementation 34 template <class _E> class initializer_list { 35 const _E *__begin_; 36 size_t __size_; 37 38 initializer_list(const _E *__b, size_t __s) : __begin_(__b), __size_(__s) {} 39 40 public: 41 typedef _E value_type; 42 typedef const _E &reference; 43 typedef const _E &const_reference; 44 typedef size_t size_type; 45 46 typedef const _E *iterator; 47 typedef const _E *const_iterator; 48 49 initializer_list() : __begin_(nullptr), __size_(0) {} 50 51 size_t size() const { return __size_; } 52 const _E *begin() const { return __begin_; } 53 const _E *end() const { return __begin_ + __size_; } 54 }; 55 } // namespace std 56 57 #if __cplusplus >= 201703L 58 59 // Test CXXDefaultInitExpr rebuild issue in 60 // https://github.com/llvm/llvm-project/pull/87933 61 namespace test_rebuild { 62 template <typename T, int> class C { 63 public: 64 C(std::initializer_list<T>); 65 }; 66 67 template <typename T> using Ptr = __remove_pointer(T) *; 68 template <typename T> C(T) -> C<Ptr<T>, sizeof(T)>; 69 70 class A { 71 public: 72 template <typename T1, typename T2> T1 *some_func(T2 &&); 73 }; 74 75 struct B : A { 76 int *ar = some_func<int>(C{some_func<int>(0)}); 77 B() {} 78 }; 79 80 int TestBody_got; 81 template <int> class Vector { 82 public: 83 Vector(std::initializer_list<int>); 84 }; 85 template <typename... Ts> Vector(Ts...) -> Vector<sizeof...(Ts)>; 86 class ProgramBuilder { 87 public: 88 template <typename T, typename ARGS> int *create(ARGS); 89 }; 90 91 struct TypeTest : ProgramBuilder { 92 int *str_f16 = create<int>(Vector{0}); 93 TypeTest() {} 94 }; 95 class TypeTest_Element_Test : TypeTest { 96 void TestBody(); 97 }; 98 void TypeTest_Element_Test::TestBody() { 99 int *expect = str_f16; 100 &TestBody_got != expect; // expected-warning {{inequality comparison result unused}} 101 } 102 } // namespace test_rebuild 103 104 // Test CXXDefaultInitExpr rebuild issue in 105 // https://github.com/llvm/llvm-project/pull/92527 106 namespace test_rebuild2 { 107 struct F { 108 int g; 109 }; 110 struct H {}; 111 struct I { 112 I(const F &); 113 I(H); 114 }; 115 struct L { 116 I i = I({.g = 0}); 117 }; 118 struct N : L {}; 119 120 void f() { 121 delete new L; // Ok 122 delete new N; // Ok 123 } 124 } // namespace test_rebuild2 125 #endif // __cplusplus >= 201703L 126 127 #if __cplusplus >= 202002L 128 // This test ensures cleanup expressions are correctly produced 129 // in the presence of default member initializers. 130 namespace PR136554 { 131 struct string { 132 constexpr string(const char*) {}; 133 constexpr ~string(); 134 }; 135 struct S; 136 struct optional { 137 template <typename U = S> 138 constexpr optional(U &&) {} 139 }; 140 struct S { 141 string a; 142 optional b; 143 int defaulted = 0; 144 } test { 145 "", { 146 { "", 0 } 147 } 148 }; 149 150 // Ensure that the this pointer is 151 // transformed without crashing 152 consteval int immediate() { return 0;} 153 struct StructWithThisInInitializer { 154 int member() const { 155 return 0; 156 } 157 int m = member() + immediate(); 158 int m2 = this->member() + immediate(); 159 }; 160 161 template <typename T> 162 struct StructWithThisInInitializerTPL { 163 template <typename U> 164 int member() const { 165 return 0; 166 } 167 int m = member<int>() + immediate(); 168 int m2 = this->member<int>() + immediate(); 169 }; 170 171 void test_this() { 172 (void)StructWithThisInInitializer{}; 173 (void)StructWithThisInInitializerTPL<int>{}; 174 } 175 176 struct ReferenceToNestedMembers { 177 int m; 178 int a = ((void)immediate(), m); // ensure g is found in the correct scope 179 int b = ((void)immediate(), this->m); // ensure g is found in the correct scope 180 }; 181 struct ReferenceToNestedMembersTest { 182 void* m = nullptr; 183 ReferenceToNestedMembers j{0}; 184 } test_reference_to_nested_members; 185 186 } 187 188 189 namespace odr_in_unevaluated_context { 190 template <typename e, bool = __is_constructible(e)> struct f { 191 using type = bool; 192 }; 193 194 template <class k, f<k>::type = false> int l; 195 int m; 196 struct p { 197 // This used to crash because m is first marked odr used 198 // during parsing, but subsequently used in an unevaluated context 199 // without being transformed. 200 int o = m; 201 p() {} 202 }; 203 204 int i = l<p>; 205 } 206 207 #endif 208