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