diff options
author | John McCall <rjmccall@apple.com> | 2011-02-19 02:53:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-02-19 02:53:41 +0000 |
commit | 15e310a3b970b64a84cb30f0005bc396b4d978cb (patch) | |
tree | a07be31cb50547b6d1a6f71a6397f500a58e300d /test/SemaCXX/undefined-internal.cpp | |
parent | 370e6e984cc32167228b66eaf9610c010da0d794 (diff) |
Warn about code that uses variables and functions with internal linkage
without defining them. This should be an error, but I'm paranoid about
"uses" that end up not actually requiring a definition. I'll revisit later.
Also, teach IR generation to not set internal linkage on variable
declarations, just for safety's sake. Doing so produces an invalid module
if the variable is not ultimately defined.
Also, fix several places in the test suite where we were using internal
functions without definitions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126016 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/undefined-internal.cpp')
-rw-r--r-- | test/SemaCXX/undefined-internal.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp new file mode 100644 index 0000000000..bb87ce0f12 --- /dev/null +++ b/test/SemaCXX/undefined-internal.cpp @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Make sure we don't produce invalid IR. +// RUN: %clang_cc1 -emit-llvm-only %s + +namespace test1 { + static void foo(); // expected-warning {{function 'test1::foo' has internal linkage but is not defined}} + template <class T> static void bar(); // expected-warning {{function 'test1::bar<int>' has internal linkage but is not defined}} + + void test() { + foo(); // expected-note {{used here}} + bar<int>(); // expected-note {{used here}} + } +} + +namespace test2 { + namespace { + void foo(); // expected-warning {{function 'test2::<anonymous namespace>::foo' has internal linkage but is not defined}} + extern int var; // expected-warning {{variable 'test2::<anonymous namespace>::var' has internal linkage but is not defined}} + template <class T> void bar(); // expected-warning {{function 'test2::<anonymous namespace>::bar<int>' has internal linkage but is not defined}} + } + void test() { + foo(); // expected-note {{used here}} + var = 0; // expected-note {{used here}} + bar<int>(); // expected-note {{used here}} + } +} + +namespace test3 { + namespace { + void foo(); + extern int var; + template <class T> void bar(); + } + + void test() { + foo(); + var = 0; + bar<int>(); + } + + namespace { + void foo() {} + int var = 0; + template <class T> void bar() {} + } +} + +namespace test4 { + namespace { + struct A { + A(); // expected-warning {{function 'test4::<anonymous namespace>::A::A' has internal linkage but is not defined}} + ~A();// expected-warning {{function 'test4::<anonymous namespace>::A::~A' has internal linkage but is not defined}} + virtual void foo(); // expected-warning {{function 'test4::<anonymous namespace>::A::foo' has internal linkage but is not defined}} + virtual void bar() = 0; + virtual void baz(); // expected-warning {{function 'test4::<anonymous namespace>::A::baz' has internal linkage but is not defined}} + }; + } + + void test(A &a) { + a.foo(); // expected-note {{used here}} + a.bar(); + a.baz(); // expected-note {{used here}} + } + + struct Test : A { + Test() {} // expected-note 2 {{used here}} + }; +} + +// rdar://problem/9014651 +namespace test5 { + namespace { + struct A {}; + } + + template <class N> struct B { + static int var; // expected-warning {{variable 'test5::B<test5::<anonymous>::A>::var' has internal linkage but is not defined}} + static void foo(); // expected-warning {{function 'test5::B<test5::<anonymous>::A>::foo' has internal linkage but is not defined}} + }; + + void test() { + B<A>::var = 0; // expected-note {{used here}} + B<A>::foo(); // expected-note {{used here}} + } +} |