xref: /llvm-project/clang/test/SemaCXX/undefined-internal.cpp (revision c9bd88e6811fb622cde644a82eac41c0b02c00ee)
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 // Make sure we don't produce invalid IR.
4 // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s
5 
6 // FIXME: Itanium shouldn't be necessary; the test should pass
7 // in MS mode too.
8 
9 namespace test1 {
10   static void foo(); // expected-warning {{function 'test1::foo' has internal linkage but is not defined}}
11   template <class T> static void bar(); // expected-warning {{function 'test1::bar<int>' has internal linkage but is not defined}}
12 
13   void test() {
14     foo(); // expected-note {{used here}}
15     bar<int>(); // expected-note {{used here}}
16   }
17 }
18 
19 namespace test2 {
20   namespace {
21     void foo(); // expected-warning {{function 'test2::<anonymous namespace>::foo' has internal linkage but is not defined}}
22     extern int var; // expected-warning {{variable 'test2::<anonymous namespace>::var' has internal linkage but is not defined}}
23     template <class T> void bar(); // expected-warning {{function 'test2::<anonymous namespace>::bar<int>' has internal linkage but is not defined}}
24   }
25   void test() {
26     foo(); // expected-note {{used here}}
27     var = 0; // expected-note {{used here}}
28     bar<int>(); // expected-note {{used here}}
29   }
30 }
31 
32 namespace test3 {
33   namespace {
34     void foo();
35     extern int var;
36     template <class T> void bar();
37   }
38 
39   void test() {
40     foo();
41     var = 0;
42     bar<int>();
43   }
44 
45   namespace {
46     void foo() {}
47     int var = 0;
48     template <class T> void bar() {}
49   }
50 }
51 
52 namespace test4 {
53   namespace {
54     struct A {
55       A(); // expected-warning {{function 'test4::<anonymous namespace>::A::A' has internal linkage but is not defined}}
56       ~A();// expected-warning {{function 'test4::<anonymous namespace>::A::~A' has internal linkage but is not defined}}
57       virtual void foo(); // expected-warning {{function 'test4::<anonymous namespace>::A::foo' has internal linkage but is not defined}}
58       virtual void bar() = 0;
59       virtual void baz(); // expected-warning {{function 'test4::<anonymous namespace>::A::baz' has internal linkage but is not defined}}
60     };
61   }
62 
63   void test(A &a) {
64     a.foo(); // expected-note {{used here}}
65     a.bar();
66     a.baz(); // expected-note {{used here}}
67   }
68 
69   struct Test : A {
70     Test() {} // expected-note 2 {{used here}}
71   };
72 }
73 
74 // rdar://problem/9014651
75 namespace test5 {
76   namespace {
77     struct A {};
78   }
79 
80   template <class N> struct B {
81     static int var; // expected-warning {{variable 'test5::B<test5::<anonymous>::A>::var' has internal linkage but is not defined}}
82     static void foo(); // expected-warning {{function 'test5::B<test5::<anonymous>::A>::foo' has internal linkage but is not defined}}
83   };
84 
85   void test() {
86     B<A>::var = 0; // expected-note {{used here}}
87     B<A>::foo(); // expected-note {{used here}}
88   }
89 }
90 
91 namespace test6 {
92   template <class T> struct A {
93     static const int zero = 0;
94     static const int one = 1;
95     static const int two = 2;
96 
97     int value;
98 
99     A() : value(zero) {
100       value = one;
101     }
102   };
103 
104   namespace { struct Internal; }
105 
106   void test() {
107     A<Internal> a;
108     a.value = A<Internal>::two;
109   }
110 }
111 
112 // We support (as an extension) private, undefined copy constructors when
113 // a temporary is bound to a reference even in C++98. Similarly, we shouldn't
114 // warn about this copy constructor being used without a definition.
115 namespace PR9323 {
116   namespace {
117     struct Uncopyable {
118       Uncopyable() {}
119     private:
120       Uncopyable(const Uncopyable&); // expected-note {{declared private here}}
121     };
122   }
123   void f(const Uncopyable&) {}
124   void test() {
125     f(Uncopyable()); // expected-warning {{C++98 requires an accessible copy constructor}}
126   };
127 }
128 
129 
130 namespace std { class type_info; };
131 namespace cxx11_odr_rules {
132   // Note: the way this test is written isn't really ideal, but there really
133   // isn't any other way to check that the odr-used logic for constants
134   // is working without working implicit capture in lambda-expressions.
135   // (The more accurate used-but-not-defined warning is the only other visible
136   // effect of accurate odr-used computation.)
137   //
138   // Note that the warning in question can trigger in cases some people would
139   // consider false positives; hopefully that happens rarely in practice.
140   //
141   // FIXME: Suppressing this test while I figure out how to fix a bug in the
142   // odr-use marking code.
143 
144   namespace {
145     struct A {
146       static const int unused = 10;
147       static const int used1 = 20; // xpected-warning {{internal linkage}}
148       static const int used2 = 20; // xpected-warning {{internal linkage}}
149       virtual ~A() {}
150     };
151   }
152 
153   void a(int,int);
154   A& p(const int&) { static A a; return a; }
155 
156   // Check handling of default arguments
157   void b(int = A::unused);
158 
159   void tests() {
160     // Basic test
161     a(A::unused, A::unused);
162 
163     // Check that nesting an unevaluated or constant-evaluated context does
164     // the right thing.
165     a(A::unused, sizeof(int[10]));
166 
167     // Check that the checks work with unevaluated contexts
168     (void)sizeof(p(A::used1));
169     (void)typeid(p(A::used1)); // xpected-note {{used here}}
170 
171     // Misc other testing
172     a(A::unused, 1 ? A::used2 : A::used2); // xpected-note {{used here}}
173     b();
174   }
175 }
176 
177 
178 namespace OverloadUse {
179   namespace {
180     void f();
181     void f(int); // expected-warning {{function 'OverloadUse::<anonymous namespace>::f' has internal linkage but is not defined}}
182   }
183   template<void x()> void t(int*) { x(); }
184   template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}}
185   void g() { long a; t<f>(&a); }
186 }
187 
188 namespace test7 {
189   typedef struct {
190     void bar();
191     void foo() {
192       bar();
193     }
194   } A;
195 }
196 
197 namespace test8 {
198   typedef struct {
199     void bar(); // expected-warning {{function 'test8::<anonymous struct>::bar' has internal linkage but is not defined}}
200     void foo() {
201       bar(); // expected-note {{used here}}
202     }
203   } *A;
204 }
205 
206 namespace test9 {
207   namespace {
208     struct X {
209       virtual void notused() = 0;
210       virtual void used() = 0; // expected-warning {{function 'test9::<anonymous namespace>::X::used' has internal linkage but is not defined}}
211     };
212   }
213   void test(X &x) {
214     x.notused();
215     x.X::used(); // expected-note {{used here}}
216   }
217 }
218 
219 namespace test10 {
220   namespace {
221     struct X {
222       virtual void notused() = 0;
223       virtual void used() = 0; // expected-warning {{function 'test10::<anonymous namespace>::X::used' has internal linkage but is not defined}}
224 
225       void test() {
226         notused();
227         (void)&X::notused;
228         (this->*&X::notused)();
229         X::used();  // expected-note {{used here}}
230       }
231     };
232     struct Y : X {
233       using X::notused;
234     };
235   }
236 }
237 
238 namespace test11 {
239   namespace {
240     struct A {
241       virtual bool operator()() const = 0;
242       virtual void operator!() const = 0;
243       virtual bool operator+(const A&) const = 0;
244       virtual int operator[](int) const = 0;
245       virtual const A* operator->() const = 0;
246       int member;
247     };
248 
249     struct B {
250       bool operator()() const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator()' has internal linkage but is not defined}}
251       void operator!() const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator!' has internal linkage but is not defined}}
252       bool operator+(const B&) const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator+' has internal linkage but is not defined}}
253       int operator[](int) const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator[]' has internal linkage but is not defined}}
254       const B* operator->() const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator->' has internal linkage but is not defined}}
255       int member;
256     };
257   }
258 
259   void test1(A &a1, A &a2) {
260     a1();
261     !a1;
262     a1 + a2;
263     a1[0];
264     (void)a1->member;
265   }
266 
267   void test2(B &b1, B &b2) {
268     b1();  // expected-note {{used here}}
269     !b1;  // expected-note {{used here}}
270     b1 + b2;  // expected-note {{used here}}
271     b1[0];  // expected-note {{used here}}
272     (void)b1->member;  // expected-note {{used here}}
273   }
274 }
275 
276 namespace test12 {
277   class T1 {}; class T2 {}; class T3 {}; class T4 {}; class T5 {}; class T6 {};
278   class T7 {};
279 
280   namespace {
281     struct Cls {
282       virtual void f(int) = 0;
283       virtual void f(int, double) = 0;
284       void g(int);  // expected-warning {{function 'test12::<anonymous namespace>::Cls::g' has internal linkage but is not defined}}
285       void g(int, double);
286       virtual operator T1() = 0;
287       virtual operator T2() = 0;
288       virtual operator T3&() = 0;
289       operator T4();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T4' has internal linkage but is not defined}}
290       operator T5();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T5' has internal linkage but is not defined}}
291       operator T6&();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator class test12::T6 &' has internal linkage but is not defined}}
292     };
293 
294     struct Cls2 {
295       Cls2(T7);  // expected-warning {{function 'test12::<anonymous namespace>::Cls2::Cls2' has internal linkage but is not defined}}
296     };
297   }
298 
299   void test(Cls &c) {
300     c.f(7);
301     c.g(7);  // expected-note {{used here}}
302     (void)static_cast<T1>(c);
303     T2 t2 = c;
304     T3 &t3 = c;
305     (void)static_cast<T4>(c); // expected-note {{used here}}
306     T5 t5 = c;  // expected-note {{used here}}
307     T6 &t6 = c;  // expected-note {{used here}}
308 
309     Cls2 obj1((T7()));  // expected-note {{used here}}
310   }
311 }
312 
313 namespace test13 {
314   namespace {
315     struct X {
316       virtual void f() { }
317     };
318 
319     struct Y : public X {
320       virtual void f() = 0;
321 
322       virtual void g() {
323         X::f();
324       }
325     };
326   }
327 }
328 
329 namespace test14 {
330   extern "C" const int foo;
331 
332   int f() {
333     return foo;
334   }
335 }
336