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 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 91 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 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}} 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 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