1 // RUN: %clang_cc1 -fsyntax-only -verify -ast-dump -std=c++2c -Wunused-parameter -Wunused -Wpre-c++26-compat %s | FileCheck %s 2 3 void static_var() { 4 static int _; // expected-note {{previous definition is here}} \ 5 // expected-note {{candidate}} 6 static int _; // expected-error {{redefinition of '_'}} 7 int _; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 8 // expected-note {{candidate}} 9 _++; // expected-error{{reference to '_' is ambiguous}} 10 } 11 12 void static_var_2() { 13 int _; // expected-note {{previous definition is here}} 14 static int _; // expected-error {{redefinition of '_'}} 15 } 16 17 void bindings() { 18 int arr[4] = {0, 1, 2, 3}; 19 auto [_, _, _, _] = arr; // expected-warning 3{{placeholder variables are incompatible with C++ standards before C++2c}} \ 20 // expected-note 4{{placeholder declared here}} 21 _ == 42; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 22 { 23 // no extension warning as we only introduce a single placeholder. 24 auto [_, a, b, c] = arr; // expected-warning {{unused variable '[_, a, b, c]'}} 25 } 26 { 27 auto [_, _, b, c] = arr; // expected-warning {{unused variable '[_, _, b, c]'}} \ 28 // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} 29 } 30 { 31 // There are only 3 extension warnings because the first 32 // introduction of `_` is valid in all C++ standards 33 auto [_, _, _, _] = arr; // expected-warning 3{{placeholder variables are incompatible with C++ standards before C++2c}} 34 } 35 } 36 37 namespace StaticBindings { 38 39 int arr[2] = {0, 1}; 40 static auto [_, _] = arr; // expected-error {{redefinition of '_'}} \ 41 // expected-note {{previous definition is here}} 42 43 void f() { 44 int arr[2] = {0, 1}; 45 static auto [_, _] = arr; // expected-error {{redefinition of '_'}} \ 46 // expected-note {{previous definition is here}} 47 } 48 49 } 50 51 void lambda() { 52 (void)[_ = 0, _ = 1] { // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 53 // expected-note 2{{placeholder declared here}} 54 (void)_++; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 55 }; 56 57 { 58 int _ = 12; 59 (void)[_ = 0]{ return _;}; // no warning (different scope) 60 } 61 62 auto GH107024 = [_ = 42]() { return _; }(); 63 } 64 65 namespace global_var { 66 int _; // expected-note {{previous definition is here}} 67 int _; // expected-error {{redefinition of '_'}} 68 } 69 70 namespace { 71 int _; // expected-note {{previous definition is here}} 72 int _; // expected-error {{redefinition of '_'}} 73 } 74 75 76 namespace global_fun { 77 void _(); 78 void _(); 79 80 void _() {} // expected-note {{previous definition is here}} 81 void _() {} // expected-error {{redefinition of '_'}} 82 void _(int){} 83 } 84 85 typedef int _; 86 typedef int _; // Type redeclaration, nothing to do with placeholders 87 88 void extern_test() { 89 extern int _; 90 extern int _; // expected-note {{candidate}} 91 int _; //expected-note {{candidate}} 92 _++; // expected-error {{reference to '_' is ambiguous}} 93 } 94 95 96 struct Members { 97 int _; // expected-note 2{{placeholder declared here}} 98 int _; // expected-warning{{placeholder variables are incompatible with C++ standards before C++2c}} \ 99 // expected-note 2{{placeholder declared here}} 100 void f() { 101 _++; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 102 } 103 void attributes() __attribute__((diagnose_if(_ != 0, "oh no!", "warning"))); // expected-error{{ambiguous reference to placeholder '_', which is defined multiple times}} 104 }; 105 106 namespace using_ { 107 int _; // expected-note {{target of using declaration}} 108 void f() { 109 int _; // expected-note {{conflicting declaration}} 110 _ = 0; 111 using using_::_; // expected-error {{target of using declaration conflicts with declaration already in scope}} 112 } 113 } 114 115 116 void call(int); 117 void test_param(int _) {} 118 void test_params(int _, int _); // expected-error {{redefinition of parameter '_'}} \ 119 // expected-note {{previous declaration is here}} 120 121 template <auto _, auto _> // expected-error {{declaration of '_' shadows template parameter}} \ 122 // expected-note {{template parameter is declared here}} 123 auto i = 0; 124 125 template <typename T> 126 concept C = requires(T _, T _) { // expected-error {{redefinition of parameter '_'}} \ 127 // expected-note {{previous declaration is here}} 128 T{}; 129 }; 130 131 struct S { 132 int a; 133 }; 134 135 void f(S a, S _) { // expected-warning {{unused parameter 'a'}} 136 137 } 138 139 void unused_warning() { 140 int _ = 12; // placeholder variable, no unused-but-set warning 141 int x = 12; // expected-warning {{unused variable 'x'}} 142 int _ = 12; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} 143 } 144 145 struct ShadowMembers { 146 int _; 147 void f() { 148 int _; 149 _ = 12; // Ok, access the local variable 150 (void)({ int _ = 12; _;}); // Ok, inside a different scope 151 } 152 }; 153 154 struct MemberPtrs { 155 int _, _; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 156 // expected-note 4{{placeholder declared here}} 157 }; 158 constexpr int oh_no = __builtin_offsetof(MemberPtrs, _); // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 159 int MemberPtrs::* ref = &MemberPtrs::_; // expected-error{{ambiguous reference to placeholder '_', which is defined multiple times}} 160 161 162 struct MemberInitializer { 163 MemberInitializer() : _(0) {} // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 164 int _, _; // expected-note 2{{placeholder declared here}} \ 165 // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} 166 }; 167 168 struct MemberAndUnion { 169 int _; // expected-note {{placeholder declared here}} 170 union { int _; int _; }; // expected-note 2 {{placeholder declared here}} \ 171 // expected-warning 2{{placeholder variables are incompatible with C++ standards before C++2c}} 172 173 174 MemberAndUnion() : _(0) {} // expected-error {{ambiguous reference to placeholder '_', which is defined multiple time}} 175 }; 176 177 struct Union { union { int _, _, _; }; }; // expected-note 3{{placeholder declared here}} \ 178 // expected-warning 2{{placeholder variables are incompatible with C++ standards before C++2c}} 179 180 void TestUnion() { 181 Union c; 182 c._ = 0; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 183 } 184 185 void AnonymousLocals() { 186 union {int _, _;}; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 187 // expected-note 2{{placeholder declared here}} 188 union {int _, _;}; // expected-warning 2{{placeholder variables are incompatible with C++ standards before C++2c}} \ 189 // expected-note 2{{placeholder declared here}} 190 _. = 0; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 191 } 192 193 namespace StaticUnions { 194 195 static union { int _ = 42; }; // expected-note {{previous declaration is here}} 196 static union { int _ = 43; }; // expected-error {{member of anonymous union redeclares '_'}} 197 198 inline void StaticUnion() { 199 static union { int _{}; }; // expected-note {{previous declaration is here}} 200 static union { int _{}; }; // expected-error {{member of anonymous union redeclares '_'}} 201 } 202 203 } 204 205 namespace TagVariables { 206 207 [[maybe_unused]] struct { 208 int _, _, _; // expected-warning 2{{placeholder variables are incompatible with C++ standards before C++2c}} 209 } a; 210 211 [[maybe_unused]] union { 212 int _, _, _; // expected-warning 2{{placeholder variables are incompatible with C++ standards before C++2c}} 213 } b; 214 215 } 216 217 namespace MemberLookupTests { 218 219 struct S { 220 int _, _; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 221 // expected-note 8{{placeholder declared here}} 222 223 void f() { 224 _ ++ ; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 225 } 226 }; 227 228 struct T : S { 229 230 }; 231 232 void Test() { 233 S s{._ =0}; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 234 S{}._; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 235 T{}._; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 236 }; 237 238 }; 239 240 namespace Bases { 241 struct S { 242 int _, _; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 243 // expected-note 2{{placeholder declared here}} 244 int a; 245 }; 246 struct T : S{ 247 int _, _; // expected-warning {{placeholder variables are incompatible with C++ standards before C++2c}} \ 248 // expected-note 2{{placeholder declared here}} 249 int a; 250 void f() { 251 _; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} 252 S::_; // expected-error {{ambiguous reference to placeholder '_', which is defined multiple times}} \ 253 // expected-error {{a type specifier is required for all declarations}} 254 } 255 }; 256 } 257 258 namespace GH114069 { 259 260 template <class T> 261 struct A { 262 T _ = 1; 263 T _ = 2; 264 T : 1; 265 T a = 3; 266 T _ = 4; 267 }; 268 269 void f() { 270 [[maybe_unused]] A<int> a; 271 } 272 273 // CHECK: NamespaceDecl {{.*}} GH114069 274 // CHECK: ClassTemplateSpecializationDecl {{.*}} struct A definition 275 // CHECK: CXXConstructorDecl {{.*}} implicit used constexpr A 'void () noexcept' 276 // CHECK-NEXT: CXXCtorInitializer Field {{.*}} '_' 'int' 277 // CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init 278 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 279 // CHECK-NEXT: CXXCtorInitializer Field {{.*}} '_' 'int' 280 // CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init 281 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2 282 // CHECK-NEXT: CXXCtorInitializer Field {{.*}} 'a' 'int' 283 // CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init 284 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3 285 // CHECK-NEXT: CXXCtorInitializer Field {{.*}} '_' 'int' 286 // CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init 287 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4 288 // CHECK-NEXT: CompoundStmt {{.*}} 289 290 } 291