diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-04-23 23:48:00 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-04-23 23:48:00 +0000 |
commit | 078b47bdba491f4b2ccf89a6ed10e9ebd350986a (patch) | |
tree | c80a715c3d24a2fce181eebc734d2a53b76c1e2a /test | |
parent | fe8b4c1fcb60d63990abaa3f3b26ab8892474351 (diff) | |
download | clang-078b47bdba491f4b2ccf89a6ed10e9ebd350986a.tar.gz |
C++ DR2387: a variable template declared wtih (or instantiated with) a
const-qualified type is not implicitly given internal linkage. But a
variable template declared 'static' is.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359048 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CXX/drs/dr0xx.cpp | 7 | ||||
-rw-r--r-- | test/CXX/drs/dr17xx.cpp | 2 | ||||
-rw-r--r-- | test/CXX/drs/dr23xx.cpp | 26 | ||||
-rw-r--r-- | test/CXX/module/module.interface/p3.cpp | 2 | ||||
-rw-r--r-- | test/CXX/module/module.interface/p5.cpp | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/cxx1y-variable-template-linkage.cpp | 54 | ||||
-rw-r--r-- | test/SemaCXX/PR10177.cpp | 3 | ||||
-rw-r--r-- | test/SemaCXX/warn-unused-filescoped.cpp | 3 | ||||
-rw-r--r-- | test/SemaCXX/warn-unused-variables.cpp | 4 |
9 files changed, 87 insertions, 20 deletions
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp index 911aab1747..53bd6f3f05 100644 --- a/test/CXX/drs/dr0xx.cpp +++ b/test/CXX/drs/dr0xx.cpp @@ -869,18 +869,17 @@ namespace dr68 { // dr68: yes } namespace dr69 { // dr69: yes - template<typename T> static void f() {} + template<typename T> static void f() {} // #dr69-f // FIXME: Should we warn here? inline void g() { f<int>(); } - // FIXME: This should be rejected, per [temp.explicit]p11. - extern template void f<char>(); + extern template void f<char>(); // expected-error {{explicit instantiation declaration of 'f' with internal linkage}} #if __cplusplus < 201103L // expected-error@-2 {{C++11 extension}} #endif template<void(*)()> struct Q {}; Q<&f<int> > q; #if __cplusplus < 201103L - // expected-error@-2 {{internal linkage}} expected-note@-11 {{here}} + // expected-error@-2 {{internal linkage}} expected-note@#dr69-f {{here}} #endif } diff --git a/test/CXX/drs/dr17xx.cpp b/test/CXX/drs/dr17xx.cpp index 9f67b24271..bf7458ea81 100644 --- a/test/CXX/drs/dr17xx.cpp +++ b/test/CXX/drs/dr17xx.cpp @@ -77,7 +77,7 @@ namespace dr1758 { // dr1758: 3.7 #endif } -namespace dr1722 { // dr1722: 9.0 +namespace dr1722 { // dr1722: 9 #if __cplusplus >= 201103L void f() { const auto lambda = [](int x) { return x + 1; }; diff --git a/test/CXX/drs/dr23xx.cpp b/test/CXX/drs/dr23xx.cpp new file mode 100644 index 0000000000..87db0d4c9b --- /dev/null +++ b/test/CXX/drs/dr23xx.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +#if __cplusplus <= 201103L +// expected-no-diagnostics +#endif + +namespace dr2387 { // dr2387: 9 +#if __cplusplus >= 201402L + template<int> int a = 0; + extern template int a<0>; // ok + + template<int> static int b = 0; + extern template int b<0>; // expected-error {{internal linkage}} + + template<int> const int c = 0; + extern template const int c<0>; // ok, has external linkage despite 'const' + + template<typename T> T d = 0; + extern template int d<int>; + extern template const int d<const int>; +#endif +} diff --git a/test/CXX/module/module.interface/p3.cpp b/test/CXX/module/module.interface/p3.cpp index 89c5e08f54..22a003550b 100644 --- a/test/CXX/module/module.interface/p3.cpp +++ b/test/CXX/module/module.interface/p3.cpp @@ -48,7 +48,7 @@ export namespace { int c; } // expected-error {{declaration of 'c' with internal namespace { // expected-note {{here}} export int d; // expected-error {{export declaration appears within anonymous namespace}} } -export template<typename> static int e; // FIXME +export template<typename> static int e; // expected-error {{declaration of 'e' with internal linkage cannot be exported}} export template<typename> static int f(); // expected-error {{declaration of 'f' with internal linkage cannot be exported}} export const int k = 5; export static union { int n; }; // expected-error {{declaration of 'n' with internal linkage cannot be exported}} diff --git a/test/CXX/module/module.interface/p5.cpp b/test/CXX/module/module.interface/p5.cpp index c4299dc04f..17c4105baa 100644 --- a/test/CXX/module/module.interface/p5.cpp +++ b/test/CXX/module/module.interface/p5.cpp @@ -14,7 +14,7 @@ static union { int sg1, sg2; }; // expected-note {{target}} namespace NS {} template<typename> int ta; -template<typename> static int sta; +template<typename> static int sta; // expected-note {{target}} template<typename> void tb(); template<typename> static void stb(); // expected-note {{target}} template<typename> struct tc {}; @@ -44,7 +44,7 @@ namespace UnnamedNS { } } -export { // expected-note 18{{here}} +export { // expected-note 19{{here}} using ::a; using ::sa; // expected-error {{using declaration referring to 'sa' with internal linkage}} using ::b; @@ -56,7 +56,7 @@ export { // expected-note 18{{here}} using ::sg1; // expected-error {{using declaration referring to 'sg1' with internal linkage}} using ::ta; - using ::sta; // FIXME {{using declaration referring to 'sta' with internal linkage}} + using ::sta; // expected-error {{using declaration referring to 'sta' with internal linkage}} using ::tb; using ::stb; // expected-error {{using declaration referring to 'stb' with internal linkage}} using ::tc; diff --git a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp index bc775568aa..c77841cabc 100644 --- a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp +++ b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp @@ -6,21 +6,61 @@ // should be 'internal global' and not 'linkonce_odr global'. template <typename T> int x = 42; - +// CHECK-DAG: @_Z1xIiE = linkonce_odr global // CHECK-DAG: @_Z1xIZL3foovE3FooE = internal global +// 'static' affects the linkage of the global +template <typename T> static int y = 42; +// CHECK-DAG: @_ZL1yIiE = internal global +// CHECK-DAG: @_ZL1yIZL3foovE3FooE = internal global + +// 'const' does not +template <typename T> const int z = 42; +// CHECK-DAG: @_Z1zIiE = linkonce_odr constant +// CHECK-DAG: @_Z1zIZL3foovE3FooE = internal constant + +template <typename T> T t = 42; +// CHECK-DAG: @_Z1tIiE = linkonce_odr global +// CHECK-DAG: @_Z1tIKiE = linkonce_odr constant + +int mode; + // CHECK-DAG: define internal dereferenceable(4) i32* @_ZL3foov( -static int &foo() { +static const int &foo() { struct Foo { }; - - // CHECK-DAG: ret i32* @_Z1xIZL3foovE3FooE - return x<Foo>; + + switch (mode) { + case 0: + // CHECK-DAG: @_Z1xIiE + return x<int>; + case 1: + // CHECK-DAG: @_Z1xIZL3foovE3FooE + return x<Foo>; + case 2: + // CHECK-DAG: @_ZL1yIiE + return y<int>; + case 3: + // CHECK-DAG: @_ZL1yIZL3foovE3FooE + return y<Foo>; + case 4: + // CHECK-DAG: @_Z1zIiE + return z<int>; + case 5: + // CHECK-DAG: @_Z1zIZL3foovE3FooE + return z<Foo>; + case 6: + // CHECK-DAG: @_Z1tIiE + return t<int>; + case 7: + // CHECK-DAG: @_Z1tIKiE + return t<const int>; + } } #if !__has_feature(cxx_exceptions) // File A // CHECKA-DAG: define dereferenceable(4) i32* @_Z3barv( -int &bar() { +const int &bar() { // CHECKA-DAG: call dereferenceable(4) i32* @_ZL3foov() return foo(); } @@ -28,7 +68,7 @@ int &bar() { #else // File B // CHECKB-DAG: declare dereferenceable(4) i32* @_Z3barv( -int &bar(); +const int &bar(); int main() { // CHECKB-DAG: call dereferenceable(4) i32* @_Z3barv() diff --git a/test/SemaCXX/PR10177.cpp b/test/SemaCXX/PR10177.cpp index 59630be508..0d2e792f52 100644 --- a/test/SemaCXX/PR10177.cpp +++ b/test/SemaCXX/PR10177.cpp @@ -57,11 +57,10 @@ namespace N { } #else -// expected-no-diagnostics namespace { template<typename> extern int n; } template<typename T> int g() { return n<int>; } -namespace { extern template int n<int>; } +namespace { extern template int n<int>; } // expected-error {{explicit instantiation declaration of 'n<int>' with internal linkage}} #endif diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp index 93c6bbd7ed..e052ecb1af 100644 --- a/test/SemaCXX/warn-unused-filescoped.cpp +++ b/test/SemaCXX/warn-unused-filescoped.cpp @@ -207,8 +207,9 @@ static void completeRedeclChainForTemplateSpecialization() { } // expected-warni namespace test10 { #if __cplusplus >= 201103L +// FIXME: Warn on template definitions with no instantiations? template<class T> -constexpr T pi = T(3.14); // expected-warning {{unused}} +constexpr T pi = T(3.14); #endif } diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp index a7ac9afc36..97634ac43c 100644 --- a/test/SemaCXX/warn-unused-variables.cpp +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -135,7 +135,9 @@ namespace PR19305 { template<typename T> int m = 0; template<typename T> int m<T*> = 0; - template<> const int m<void> = 0; // expected-warning {{unused variable}} + // This has external linkage, so could be referenced by a declaration in a + // different translation unit. + template<> const int m<void> = 0; // no warning } namespace ctor_with_cleanups { |