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