diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-28 22:03:51 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-28 22:03:51 +0000 |
| commit | 902befa2773dfb3411118d0325e5ace00460c1d2 (patch) | |
| tree | 134cc5d6a3db60545b950f3edc645a45a4a61ec5 /clang/test | |
| parent | 4d18c9cc4e7f30a74703676c02e3399ebb2cb49f (diff) | |
| download | bcm5719-llvm-902befa2773dfb3411118d0325e5ace00460c1d2.tar.gz bcm5719-llvm-902befa2773dfb3411118d0325e5ace00460c1d2.zip | |
PR7927, PR16247: Reimplement handling of matching extern "C" declarations
across scopes.
When we declare an extern "C" name that is not a redeclaration of an entity in
the same scope, check whether it redeclares some extern "C" entity from another
scope, and if not, check whether it conflicts with a (non-extern-"C") entity in
the translation unit.
When we declare a name in the translation unit that is not a redeclaration,
check whether it conflicts with any extern "C" entities (possibly from other
scopes).
llvm-svn: 185229
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CXX/class.access/class.friend/p1.cpp | 10 | ||||
| -rw-r--r-- | clang/test/Sema/overloadable.c | 15 | ||||
| -rw-r--r-- | clang/test/SemaCXX/extern-c.cpp | 61 | ||||
| -rw-r--r-- | clang/test/SemaCXX/friend.cpp | 2 | ||||
| -rw-r--r-- | clang/test/SemaCXX/linkage-spec.cpp | 43 | ||||
| -rw-r--r-- | clang/test/SemaCXX/linkage2.cpp | 12 |
6 files changed, 120 insertions, 23 deletions
diff --git a/clang/test/CXX/class.access/class.friend/p1.cpp b/clang/test/CXX/class.access/class.friend/p1.cpp index 19d94cfdd5f..1a519dcc3e5 100644 --- a/clang/test/CXX/class.access/class.friend/p1.cpp +++ b/clang/test/CXX/class.access/class.friend/p1.cpp @@ -287,22 +287,22 @@ namespace test9 { // PR7230 namespace test10 { - extern "C" void f(void); - extern "C" void g(void); + extern "C" void test10_f(void); + extern "C" void test10_g(void); namespace NS { class C { void foo(void); // expected-note {{declared private here}} - friend void test10::f(void); + friend void test10::test10_f(void); }; static C* bar; } - void f(void) { + void test10_f(void) { NS::bar->foo(); } - void g(void) { + void test10_g(void) { NS::bar->foo(); // expected-error {{private member}} } } diff --git a/clang/test/Sema/overloadable.c b/clang/test/Sema/overloadable.c index 5d39f15ec81..ad021898f2a 100644 --- a/clang/test/Sema/overloadable.c +++ b/clang/test/Sema/overloadable.c @@ -69,3 +69,18 @@ void test() { f0(); f1(); } + +void before_local_1(int) __attribute__((overloadable)); // expected-note {{here}} +void before_local_2(int); // expected-note {{here}} +void before_local_3(int) __attribute__((overloadable)); +void local() { + void before_local_1(char); // expected-error {{must have the 'overloadable' attribute}} + void before_local_2(char) __attribute__((overloadable)); // expected-error {{conflicting types}} + void before_local_3(char) __attribute__((overloadable)); + void after_local_1(char); // expected-note {{here}} + void after_local_2(char) __attribute__((overloadable)); // expected-note {{here}} + void after_local_3(char) __attribute__((overloadable)); +} +void after_local_1(int) __attribute__((overloadable)); // expected-error {{conflicting types}} +void after_local_2(int); // expected-error {{must have the 'overloadable' attribute}} +void after_local_3(int) __attribute__((overloadable)); diff --git a/clang/test/SemaCXX/extern-c.cpp b/clang/test/SemaCXX/extern-c.cpp index 220b2a8dc1e..aacc0ffb158 100644 --- a/clang/test/SemaCXX/extern-c.cpp +++ b/clang/test/SemaCXX/extern-c.cpp @@ -3,20 +3,20 @@ namespace test1 { extern "C" { void test1_f() { - void test1_g(int); // expected-note {{previous declaration is here}} + void test1_g(int); // expected-note {{declared with C language linkage here}} } } } -int test1_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} +int test1_g(int); // expected-error {{declaration of 'test1_g' in global scope conflicts with declaration with C language linkage}} namespace test2 { extern "C" { void test2_f() { - extern int test2_x; // expected-note {{previous definition is here}} + extern int test2_x; // expected-note {{declared with C language linkage here}} } } } -float test2_x; // expected-error {{redefinition of 'test2_x' with a different type: 'float' vs 'int'}} +float test2_x; // expected-error {{declaration of 'test2_x' in global scope conflicts with declaration with C language linkage}} namespace test3 { extern "C" { @@ -31,18 +31,18 @@ namespace test3 { extern "C" { void test4_f() { - extern int test4_b; // expected-note {{previous definition is here}} + extern int test4_b; // expected-note {{declared with C language linkage here}} } } -static float test4_b; // expected-error {{redefinition of 'test4_b' with a different type: 'float' vs 'int'}} +static float test4_b; // expected-error {{declaration of 'test4_b' in global scope conflicts with declaration with C language linkage}} extern "C" { void test5_f() { - extern int test5_b; // expected-note {{previous definition is here}} + extern int test5_b; // expected-note {{declared with C language linkage here}} } } extern "C" { - static float test5_b; // expected-error {{redefinition of 'test5_b' with a different type: 'float' vs 'int'}} + static float test5_b; // expected-error {{declaration of 'test5_b' in global scope conflicts with declaration with C language linkage}} } extern "C" { @@ -69,11 +69,11 @@ namespace linkage { } } namespace from_outer { - void linkage_from_outer_1(); + void linkage_from_outer_1(); // expected-note {{previous}} void linkage_from_outer_2(); // expected-note {{previous}} extern "C" { - void linkage_from_outer_1(int); // expected-note {{previous}} - void linkage_from_outer_1(); // expected-error {{conflicting types}} + void linkage_from_outer_1(int); + void linkage_from_outer_1(); // expected-error {{different language linkage}} void linkage_from_outer_2(); // expected-error {{different language linkage}} } } @@ -98,11 +98,44 @@ namespace linkage { } } -void lookup_in_global_f(); +void lookup_in_global_f(); // expected-note {{here}} namespace lookup_in_global { void lookup_in_global_f(); + void lookup_in_global_g(); extern "C" { - // FIXME: We should reject this. - void lookup_in_global_f(int); + void lookup_in_global_f(int); // expected-error {{conflicts with declaration in global scope}} + void lookup_in_global_g(int); // expected-note {{here}} } } +void lookup_in_global_g(); // expected-error {{conflicts with declaration with C language linkage}} + +namespace N1 { + extern "C" int different_kind_1; // expected-note {{here}} + extern "C" void different_kind_2(); // expected-note {{here}} +} +namespace N2 { + extern "C" void different_kind_1(); // expected-error {{different kind of symbol}} + extern "C" int different_kind_2; // expected-error {{different kind of symbol}} +} + +extern "C" { + struct stat {}; + void stat(struct stat); +} +namespace X { + extern "C" { + void stat(struct ::stat); + } +} + +extern "C" void name_with_using_decl_1(int); +namespace using_decl { + void name_with_using_decl_1(); + void name_with_using_decl_2(); + void name_with_using_decl_3(); +} +using using_decl::name_with_using_decl_1; +using using_decl::name_with_using_decl_2; +extern "C" void name_with_using_decl_2(int); +extern "C" void name_with_using_decl_3(int); +using using_decl::name_with_using_decl_3; diff --git a/clang/test/SemaCXX/friend.cpp b/clang/test/SemaCXX/friend.cpp index 5daadf0e729..ce2f34ff6b9 100644 --- a/clang/test/SemaCXX/friend.cpp +++ b/clang/test/SemaCXX/friend.cpp @@ -134,7 +134,7 @@ namespace test6_3 { namespace test7 { extern "C" { class X { - friend int f() { return 42; } + friend int test7_f() { return 42; } }; } } diff --git a/clang/test/SemaCXX/linkage-spec.cpp b/clang/test/SemaCXX/linkage-spec.cpp index fc14081247a..355a8787931 100644 --- a/clang/test/SemaCXX/linkage-spec.cpp +++ b/clang/test/SemaCXX/linkage-spec.cpp @@ -41,20 +41,32 @@ namespace pr5430 { using namespace pr5430; extern "C" void pr5430::func(void) { } -// PR5404 -int f2(char *) +// PR5405 +int f2(char *) // expected-note {{here}} { return 0; } extern "C" { - int f2(int) + int f2(int) // expected-error {{with C language linkage conflicts with declaration in global scope}} { return f2((char *)0); } } +namespace PR5405 { + int f2b(char *) { + return 0; + } + + extern "C" { + int f2b(int) { + return f2b((char *)0); // ok + } + } +} + // PR6991 extern "C" typedef int (*PutcFunc_t)(int); @@ -117,3 +129,28 @@ namespace pr14958 { extern "C" void PR16167; // expected-error {{variable has incomplete type 'void'}} extern void PR16167_0; // expected-error {{variable has incomplete type 'void'}} + +// PR7927 +enum T_7927 { + E_7927 +}; + +extern "C" void f_pr7927(int); + +namespace { + extern "C" void f_pr7927(int); + + void foo_pr7927() { + f_pr7927(E_7927); + f_pr7927(0); + ::f_pr7927(E_7927); + ::f_pr7927(0); + } +} + +void bar_pr7927() { + f_pr7927(E_7927); + f_pr7927(0); + ::f_pr7927(E_7927); + ::f_pr7927(0); +} diff --git a/clang/test/SemaCXX/linkage2.cpp b/clang/test/SemaCXX/linkage2.cpp index a811575c612..c97a2f4ba74 100644 --- a/clang/test/SemaCXX/linkage2.cpp +++ b/clang/test/SemaCXX/linkage2.cpp @@ -201,3 +201,15 @@ namespace test18 { } void *h() { return f(); } } + +extern "C" void pr16247_foo(int); // expected-note {{here}} +static void pr16247_foo(double); // expected-error {{conflicts with declaration with C language linkage}} +void pr16247_foo(int) {} +void pr16247_foo(double) {} + +namespace PR16247 { + extern "C" void pr16247_bar(int); + static void pr16247_bar(double); + void pr16247_bar(int) {} + void pr16247_bar(double) {} +} |

