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