xref: /llvm-project/clang/test/SemaCXX/using-if-exists.cpp (revision 369c64839946d89cf5697550b6feeea031b2f270)
1*369c6483SErik Pilkington // RUN: %clang_cc1 -std=c++20 -fsyntax-only %s -verify
2*369c6483SErik Pilkington 
3*369c6483SErik Pilkington #define UIE __attribute__((using_if_exists))
4*369c6483SErik Pilkington 
5*369c6483SErik Pilkington namespace test_basic {
6*369c6483SErik Pilkington namespace NS {}
7*369c6483SErik Pilkington 
8*369c6483SErik Pilkington using NS::x UIE; // expected-note{{using declaration annotated with 'using_if_exists' here}}
9*369c6483SErik Pilkington x usex();        // expected-error{{reference to unresolved using declaration}}
10*369c6483SErik Pilkington 
11*369c6483SErik Pilkington using NotNS::x UIE; // expected-error{{use of undeclared identifier 'NotNS'}}
12*369c6483SErik Pilkington 
13*369c6483SErik Pilkington using NS::NotNS::x UIE; // expected-error{{no member named 'NotNS' in namespace 'test_basic::NS'}}
14*369c6483SErik Pilkington } // namespace test_basic
15*369c6483SErik Pilkington 
16*369c6483SErik Pilkington namespace test_redecl {
17*369c6483SErik Pilkington namespace NS {}
18*369c6483SErik Pilkington 
19*369c6483SErik Pilkington using NS::x UIE;
20*369c6483SErik Pilkington using NS::x UIE;
21*369c6483SErik Pilkington 
22*369c6483SErik Pilkington namespace NS1 {}
23*369c6483SErik Pilkington namespace NS2 {}
24*369c6483SErik Pilkington namespace NS3 {
25*369c6483SErik Pilkington int A();     // expected-note{{target of using declaration}}
26*369c6483SErik Pilkington struct B {}; // expected-note{{target of using declaration}}
27*369c6483SErik Pilkington int C();     // expected-note{{conflicting declaration}}
28*369c6483SErik Pilkington struct D {}; // expected-note{{conflicting declaration}}
29*369c6483SErik Pilkington } // namespace NS3
30*369c6483SErik Pilkington 
31*369c6483SErik Pilkington using NS1::A UIE;
32*369c6483SErik Pilkington using NS2::A UIE; // expected-note{{using declaration annotated with 'using_if_exists' here}} expected-note{{conflicting declaration}}
33*369c6483SErik Pilkington using NS3::A UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}}
34*369c6483SErik Pilkington int i = A();      // expected-error{{reference to unresolved using declaration}}
35*369c6483SErik Pilkington 
36*369c6483SErik Pilkington using NS1::B UIE;
37*369c6483SErik Pilkington using NS2::B UIE; // expected-note{{conflicting declaration}} expected-note{{using declaration annotated with 'using_if_exists' here}}
38*369c6483SErik Pilkington using NS3::B UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}}
39*369c6483SErik Pilkington B myB;            // expected-error{{reference to unresolved using declaration}}
40*369c6483SErik Pilkington 
41*369c6483SErik Pilkington using NS3::C UIE;
42*369c6483SErik Pilkington using NS2::C UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}} expected-note{{target of using declaration}}
43*369c6483SErik Pilkington int j = C();
44*369c6483SErik Pilkington 
45*369c6483SErik Pilkington using NS3::D UIE;
46*369c6483SErik Pilkington using NS2::D UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}} expected-note{{target of using declaration}}
47*369c6483SErik Pilkington D myD;
48*369c6483SErik Pilkington } // namespace test_redecl
49*369c6483SErik Pilkington 
50*369c6483SErik Pilkington namespace test_dependent {
51*369c6483SErik Pilkington template <class B>
52*369c6483SErik Pilkington struct S : B {
53*369c6483SErik Pilkington   using B::mf UIE;          // expected-note 3 {{using declaration annotated with 'using_if_exists' here}}
54*369c6483SErik Pilkington   using typename B::mt UIE; // expected-note{{using declaration annotated with 'using_if_exists' here}}
55*369c6483SErik Pilkington };
56*369c6483SErik Pilkington 
57*369c6483SErik Pilkington struct BaseEmpty {
58*369c6483SErik Pilkington };
59*369c6483SErik Pilkington struct BaseNonEmpty {
60*369c6483SErik Pilkington   void mf();
61*369c6483SErik Pilkington   typedef int mt;
62*369c6483SErik Pilkington };
63*369c6483SErik Pilkington 
64*369c6483SErik Pilkington template <class Base>
65*369c6483SErik Pilkington struct UseCtor : Base {
66*369c6483SErik Pilkington   using Base::Base UIE; // expected-error{{'using_if_exists' attribute cannot be applied to an inheriting constructor}}
67*369c6483SErik Pilkington };
68*369c6483SErik Pilkington struct BaseCtor {};
69*369c6483SErik Pilkington 
f()70*369c6483SErik Pilkington void f() {
71*369c6483SErik Pilkington   S<BaseEmpty> empty;
72*369c6483SErik Pilkington   S<BaseNonEmpty> nonempty;
73*369c6483SErik Pilkington   empty.mf(); // expected-error {{reference to unresolved using declaration}}
74*369c6483SErik Pilkington   nonempty.mf();
75*369c6483SErik Pilkington   (&empty)->mf(); // expected-error {{reference to unresolved using declaration}}
76*369c6483SErik Pilkington   (&nonempty)->mf();
77*369c6483SErik Pilkington 
78*369c6483SErik Pilkington   S<BaseEmpty>::mt y; // expected-error {{reference to unresolved using declaration}}
79*369c6483SErik Pilkington   S<BaseNonEmpty>::mt z;
80*369c6483SErik Pilkington 
81*369c6483SErik Pilkington   S<BaseEmpty>::mf(); // expected-error {{reference to unresolved using declaration}}
82*369c6483SErik Pilkington 
83*369c6483SErik Pilkington   UseCtor<BaseCtor> usector;
84*369c6483SErik Pilkington }
85*369c6483SErik Pilkington 
86*369c6483SErik Pilkington template <class B>
87*369c6483SErik Pilkington struct Implicit : B {
88*369c6483SErik Pilkington   using B::mf UIE;          // expected-note {{using declaration annotated with 'using_if_exists' here}}
89*369c6483SErik Pilkington   using typename B::mt UIE; // expected-note 2 {{using declaration annotated with 'using_if_exists' here}}
90*369c6483SErik Pilkington 
usetest_dependent::Implicit91*369c6483SErik Pilkington   void use() {
92*369c6483SErik Pilkington     mf(); // expected-error {{reference to unresolved using declaration}}
93*369c6483SErik Pilkington     mt x; // expected-error {{reference to unresolved using declaration}}
94*369c6483SErik Pilkington   }
95*369c6483SErik Pilkington 
96*369c6483SErik Pilkington   mt alsoUse(); // expected-error {{reference to unresolved using declaration}}
97*369c6483SErik Pilkington };
98*369c6483SErik Pilkington 
testImplicit()99*369c6483SErik Pilkington void testImplicit() {
100*369c6483SErik Pilkington   Implicit<BaseNonEmpty> nonempty;
101*369c6483SErik Pilkington   Implicit<BaseEmpty> empty; // expected-note {{in instantiation}}
102*369c6483SErik Pilkington   nonempty.use();
103*369c6483SErik Pilkington   empty.use(); // expected-note {{in instantiation}}
104*369c6483SErik Pilkington }
105*369c6483SErik Pilkington 
106*369c6483SErik Pilkington template <class>
107*369c6483SErik Pilkington struct NonDep : BaseEmpty {
108*369c6483SErik Pilkington   using BaseEmpty::x UIE; // expected-note{{using declaration annotated with 'using_if_exists' here}}
109*369c6483SErik Pilkington   x y();                  // expected-error{{reference to unresolved using declaration}}
110*369c6483SErik Pilkington };
111*369c6483SErik Pilkington } // namespace test_dependent
112*369c6483SErik Pilkington 
113*369c6483SErik Pilkington namespace test_using_pack {
114*369c6483SErik Pilkington template <class... Ts>
115*369c6483SErik Pilkington struct S : Ts... {
116*369c6483SErik Pilkington   using typename Ts::x... UIE; // expected-error 2 {{target of using declaration conflicts with declaration already in scope}} expected-note{{conflicting declaration}} expected-note{{target of using declaration}}
117*369c6483SErik Pilkington };
118*369c6483SErik Pilkington 
119*369c6483SErik Pilkington struct E1 {};
120*369c6483SErik Pilkington struct E2 {};
121*369c6483SErik Pilkington S<E1, E2> a;
122*369c6483SErik Pilkington 
123*369c6483SErik Pilkington struct F1 {
124*369c6483SErik Pilkington   typedef int x; // expected-note 2 {{conflicting declaration}}
125*369c6483SErik Pilkington };
126*369c6483SErik Pilkington struct F2 {
127*369c6483SErik Pilkington   typedef int x; // expected-note 2 {{target of using declaration}}
128*369c6483SErik Pilkington };
129*369c6483SErik Pilkington S<F1, F2> b;
130*369c6483SErik Pilkington 
131*369c6483SErik Pilkington S<E1, F2> c; // expected-note{{in instantiation of template class}}
132*369c6483SErik Pilkington S<F1, E2> d; // expected-note{{in instantiation of template class}}
133*369c6483SErik Pilkington 
134*369c6483SErik Pilkington template <class... Ts>
135*369c6483SErik Pilkington struct S2 : Ts... {
136*369c6483SErik Pilkington   using typename Ts::x... UIE; // expected-error 2 {{target of using declaration conflicts with declaration already in scope}} expected-note 3 {{using declaration annotated with 'using_if_exists' here}} expected-note{{conflicting declaration}} expected-note{{target of using declaration}}
137*369c6483SErik Pilkington 
138*369c6483SErik Pilkington   x mem(); // expected-error 3 {{reference to unresolved using declaration}}
139*369c6483SErik Pilkington };
140*369c6483SErik Pilkington 
141*369c6483SErik Pilkington S2<E1, E2> e; // expected-note{{in instantiation of template class}}
142*369c6483SErik Pilkington S2<F1, F2> f;
143*369c6483SErik Pilkington S2<E1, F2> g; // expected-note{{in instantiation of template class}}
144*369c6483SErik Pilkington S2<F1, E2> h; // expected-note{{in instantiation of template class}}
145*369c6483SErik Pilkington 
146*369c6483SErik Pilkington template <class... Ts>
147*369c6483SErik Pilkington struct S3 : protected Ts... {
148*369c6483SErik Pilkington   using Ts::m... UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}} expected-note{{target of using declaration}}
149*369c6483SErik Pilkington };
150*369c6483SErik Pilkington struct B1 {
151*369c6483SErik Pilkington   enum { m }; // expected-note{{conflicting declaration}}
152*369c6483SErik Pilkington };
153*369c6483SErik Pilkington struct B2 {};
154*369c6483SErik Pilkington 
155*369c6483SErik Pilkington S3<B1, B2> i; // expected-note{{in instantiation of template}}
156*369c6483SErik Pilkington S<B2, B1> j;
157*369c6483SErik Pilkington 
158*369c6483SErik Pilkington } // namespace test_using_pack
159*369c6483SErik Pilkington 
160*369c6483SErik Pilkington namespace test_nested {
161*369c6483SErik Pilkington namespace NS {}
162*369c6483SErik Pilkington 
163*369c6483SErik Pilkington using NS::x UIE; // expected-note {{using declaration annotated with 'using_if_exists' here}}
164*369c6483SErik Pilkington 
165*369c6483SErik Pilkington namespace NS2 {
166*369c6483SErik Pilkington using ::test_nested::x UIE;
167*369c6483SErik Pilkington }
168*369c6483SErik Pilkington 
169*369c6483SErik Pilkington NS2::x y; // expected-error {{reference to unresolved using declaration}}
170*369c6483SErik Pilkington } // namespace test_nested
171*369c6483SErik Pilkington 
172*369c6483SErik Pilkington namespace test_scope {
173*369c6483SErik Pilkington int x; // expected-note{{conflicting declaration}}
f()174*369c6483SErik Pilkington void f() {
175*369c6483SErik Pilkington   int x; // expected-note{{conflicting declaration}}
176*369c6483SErik Pilkington   {
177*369c6483SErik Pilkington     using ::x UIE; // expected-note {{using declaration annotated with 'using_if_exists' here}}
178*369c6483SErik Pilkington     (void)x;       // expected-error {{reference to unresolved using declaration}}
179*369c6483SErik Pilkington   }
180*369c6483SErik Pilkington 
181*369c6483SErik Pilkington   {
182*369c6483SErik Pilkington     using test_scope::x;
183*369c6483SErik Pilkington     using ::x UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}} expected-note{{target of using declaration}}
184*369c6483SErik Pilkington     (void)x;
185*369c6483SErik Pilkington   }
186*369c6483SErik Pilkington 
187*369c6483SErik Pilkington   (void)x;
188*369c6483SErik Pilkington 
189*369c6483SErik Pilkington   using ::x UIE; // expected-error{{target of using declaration conflicts with declaration already in scope}} expected-note{{target of using declaration}}
190*369c6483SErik Pilkington   (void)x;
191*369c6483SErik Pilkington }
192*369c6483SErik Pilkington } // namespace test_scope
193*369c6483SErik Pilkington 
194*369c6483SErik Pilkington namespace test_appertains_to {
195*369c6483SErik Pilkington namespace NS {
196*369c6483SErik Pilkington typedef int x;
197*369c6483SErik Pilkington }
198*369c6483SErik Pilkington 
199*369c6483SErik Pilkington // FIXME: This diagnostics is wrong.
200*369c6483SErik Pilkington using alias UIE = NS::x; // expected-error {{'using_if_exists' attribute only applies to named declarations, types, and value declarations}}
201*369c6483SErik Pilkington 
202*369c6483SErik Pilkington template <class>
203*369c6483SErik Pilkington using template_alias UIE = NS::x; // expected-error {{'using_if_exists' attribute only applies to named declarations, types, and value declarations}}
204*369c6483SErik Pilkington 
205*369c6483SErik Pilkington void f() UIE; // expected-error {{'using_if_exists' attribute only applies to named declarations, types, and value declarations}}
206*369c6483SErik Pilkington 
207*369c6483SErik Pilkington using namespace NS UIE; // expected-error {{'using_if_exists' attribute only applies to named declarations, types, and value declarations}}
208*369c6483SErik Pilkington } // namespace test_appertains_to
209*369c6483SErik Pilkington 
210*369c6483SErik Pilkington typedef int *fake_FILE;
211*369c6483SErik Pilkington int fake_printf();
212*369c6483SErik Pilkington 
213*369c6483SErik Pilkington namespace std {
214*369c6483SErik Pilkington using ::fake_FILE UIE;
215*369c6483SErik Pilkington using ::fake_printf UIE;
216*369c6483SErik Pilkington using ::fake_fopen UIE;  // expected-note {{using declaration annotated with 'using_if_exists' here}}
217*369c6483SErik Pilkington using ::fake_size_t UIE; // expected-note {{using declaration annotated with 'using_if_exists' here}}
218*369c6483SErik Pilkington } // namespace std
219*369c6483SErik Pilkington 
main()220*369c6483SErik Pilkington int main() {
221*369c6483SErik Pilkington   std::fake_FILE file;
222*369c6483SErik Pilkington   file = std::fake_fopen(); // expected-error {{reference to unresolved using declaration}} expected-error{{incompatible integer to pointer}}
223*369c6483SErik Pilkington   std::fake_size_t size;    // expected-error {{reference to unresolved using declaration}}
224*369c6483SErik Pilkington   size = fake_printf();
225*369c6483SErik Pilkington   size = std::fake_printf();
226*369c6483SErik Pilkington }
227