// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s #ifdef PRECXX11 #define CONST const #else #define CONST constexpr #endif template T pi = T(3.1415926535897932385); // expected-note 2{{declared here}} template CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}} template extern CONST T vc; #ifndef PRECXX11 // expected-error@-2 {{constexpr variable declaration must be a definition}} #endif namespace use_in_top_level_funcs { void good() { int ipi = pi; int icpi = cpi; double dpi = pi; double dcpi = cpi; } void no_deduce() { // template arguments are not deduced for uses of variable templates. int ipi = pi; // expected-error {{cannot refer to variable template 'pi' without a template argument list}} int icpi = cpi; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}} } template T circular_area(T r) { return pi * r * r; } template CONST T const_circular_area(T r) { return cpi * r * r; } double use_circular_area(double r) { CONST float t = const_circular_area(2.0) - 12; #ifndef PRECXX11 static_assert(const_circular_area(2) == 12, ""); CONST int test = (t > 0) && (t < 1); static_assert(test, ""); #endif return circular_area(r); } } namespace shadow { void foo() { int ipi0 = pi; int pi; // expected-note {{found}} int a = pi; int ipi = pi; // expected-error {{'pi' does not name a template but is followed by template arguments; did you mean '::pi'?}} } } namespace odr_tmpl { namespace pv_cvt { int v; // expected-note {{previous definition is here}} template T v; // expected-error {{redefinition of 'v' as different kind of symbol}} } namespace pvt_cv { template T v; // expected-note {{previous definition is here}} int v; // expected-error {{redefinition of 'v' as different kind of symbol}} } namespace pvt_cvt { template T v0; // expected-note {{previous definition is here}} template T v0; // expected-error {{redefinition of 'v0'}} template T v; // expected-note {{previous definition is here}} template int v; // expected-error {{redefinition of 'v'}} template extern int v1; // expected-note {{previous template declaration is here}} template int v1; // expected-error {{template parameter has a different kind in template redeclaration}} } namespace pvt_use { template T v; v = 10; // expected-error {{C++ requires a type specifier for all declarations}} } namespace pvt_diff_params { template T v; // expected-note 2{{previous template declaration is here}} template T v; // expected-error {{too few template parameters in template redeclaration}} template T v; // expected-error {{too many template parameters in template redeclaration}} } namespace pvt_extern { template T v = T(); template extern T v; // redeclaration is allowed \ // expected-note {{previous declaration is here}} template extern int v; // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}} #ifndef PRECXX11 template extern auto v; // expected-error {{declaration of variable 'v' with deduced type 'auto' requires an initializer}} #endif template T var = T(); // expected-note {{previous definition is here}} extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}} } #ifndef PRECXX11 namespace pvt_auto { template auto v0; // expected-error {{declaration of variable 'v0' with deduced type 'auto' requires an initializer}} template auto v1 = T(); // expected-note {{previous definition is here}} template int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}} template auto v2 = T(); // expected-note {{previous definition is here}} template T v2; // expected-error {{redefinition of 'v2'}} template auto v3 = T(); // expected-note {{previous definition is here}} template extern T v3; // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}} template auto v4 = T(); template extern auto v4; // expected-error {{declaration of variable 'v4' with deduced type 'auto' requires an initializer}} } #endif } namespace explicit_instantiation { template T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}} template float pi0a; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}} template T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}} template CONST int pi0b; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}} template T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}} template int pi0c; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}} template T pi0 = T(3.1415926535897932385); template int pi0; // expected-note {{previous explicit instantiation is here}} template int pi0; // expected-error {{duplicate explicit instantiation of 'pi0'}} template CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}} template int pi1a; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}} template CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}} template int pi1b; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}} template CONST T pi1 = T(3.1415926535897932385); template CONST int pi1; // expected-note {{previous explicit instantiation is here}} template CONST int pi1; // expected-error {{duplicate explicit instantiation of 'pi1'}} #ifndef PRECXX11 namespace auto_var { template auto var0 = T(); template auto var0; // expected-error {{'auto' variable template instantiation is not allowed}} template auto var = T(); template int var; } #endif template int missing_args; // expected-note {{here}} template int missing_args; // expected-error {{must specify a template argument list}} namespace extern_var { // TODO: } } namespace explicit_specialization { namespace good { template CONST int pi2 = 1; template CONST int pi2 = 2; template CONST int pi2 = 3; template<> CONST int pi2 = 4; #ifndef PRECXX11 void foo() { static_assert(pi2 == 4, ""); static_assert(pi2 == 2, ""); static_assert(pi2 == 3, ""); static_assert(pi2 == pi2, ""); static_assert(pi2 == 1, ""); static_assert(pi2 == pi2, ""); } #endif } namespace ambiguous { template CONST int pi2 = 1; template CONST int pi2 = 2; // expected-note {{partial specialization matches [with T = int]}} template CONST int pi2 = 3; // expected-note {{partial specialization matches [with T = int]}} void foo() { int a = pi2; // expected-error {{ambiguous partial specializations of 'pi2'}} } } namespace type_changes { template T pi0 = T(3.1415926535897932385); template<> float pi0 = 10; template<> int pi0 = 10; template T pi1 = T(3.1415926535897932385); template<> CONST int pi1 = 10; template T pi2 = T(3.1415926535897932385); template<> int pi2 = 10; template CONST T pi4 = T(3.1415926535897932385); template<> int pi4 = 10; } namespace redefinition { template T pi0 = T(3.1415926535897932385); template<> int pi0 = 10; // expected-note 3{{previous definition is here}} #ifndef PRECXX11 // expected-note@-2 {{previous definition is here}} #endif template<> int pi0 = 10; // expected-error {{redefinition of 'pi0'}} template<> CONST int pi0 = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}} template<> float pi0 = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}} #ifndef PRECXX11 template<> auto pi0 = 10; // expected-error {{redefinition of 'pi0'}} #endif template CONST T pi1 = T(3.1415926535897932385); template<> CONST int pi1 = 10; // expected-note {{previous definition is here}} template<> CONST int pi1 = 10; // expected-error {{redefinition of 'pi1'}} } namespace before_instantiation { template T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}} template<> int pi0 = 10; // expected-note 2{{previous template specialization is here}} template int pi0; // expected-warning {{has no effect}} template float pi0; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}} template CONST int pi2 = 1; template CONST int pi2 = 2; template CONST int pi2; } namespace after_instantiation { template T pi0 = T(3.1415926535897932385); template int pi0; // expected-note 2{{explicit instantiation first required here}} template<> int pi0 = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}} template<> float pi0; // expected-error {{explicit specialization of 'pi0' after instantiation}} template CONST int pi2 = 1; template CONST int pi2; template CONST int pi2 = 2; } #ifndef PRECXX11 namespace auto_var { template auto var0 = T(); template auto var0 = T(); template<> auto var0 = 7; template auto var = T(); template T var = T(5); template<> int var = 7; void foo() { int i0 = var0; int b = var; } } #endif namespace extern_var { // TODO: } namespace diff_type { // TODO: template T* var = new T(); #ifndef PRECXX11 template auto var = T(); // expected-note {{previous definition is here}} template T var = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}} #endif } } namespace narrowing { template T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}} #ifndef PRECXX11 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\ // expected-note@-2 {{insert an explicit cast to silence this issue}} #endif int k = v; // expected-note {{in instantiation of variable template specialization 'narrowing::v' requested here}} } namespace use_in_structs { // TODO: } namespace attributes { // TODO: } #ifndef PRECXX11 namespace arrays { template T* arr = new T[10]{T(10), T(23)}; float f = 10.5; template<> float* arr = &f; void bar() { int *iarr = arr; iarr[0] = 1; iarr[2] = 3; iarr[6] = -2; float ff = *arr; float nof = arr[3]; // No bounds-check in C++ } } #endif namespace nested { namespace n0a { template T pi0a = T(3.1415926535897932385); } using namespace n0a; int i0a = pi0a; template float pi0a; float f0a = pi0a; template<> double pi0a = 5.2; double d0a = pi0a; namespace n0b { template T pi0b = T(3.1415926535897932385); } int i0b = n0b::pi0b; template float n0b::pi0b; float f0b = n0b::pi0b; template<> double n0b::pi0b = 5.2; double d0b = n0b::pi0b; namespace n1 { template T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}} #ifndef PRECXX11 // expected-note@-2 {{explicit instantiation refers here}} #endif template T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}} #ifndef PRECXX11 // expected-note@-2 {{explicit instantiation refers here}} #endif } namespace use_n1a { using namespace n1; int i1 = pi1a; template float pi1a; #ifndef PRECXX11 // expected-error@-2 {{explicit instantiation of 'pi1a' not in a namespace enclosing 'n1'}} #endif float f1 = pi1a; template<> double pi1a = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}} double d1 = pi1a; } namespace use_n1b { int i1 = n1::pi1b; template float n1::pi1b; #ifndef PRECXX11 // expected-error@-2 {{explicit instantiation of 'pi1b' not in a namespace enclosing 'n1'}} #endif float f1 = n1::pi1b; template<> double n1::pi1b = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \ // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}} double d1 = n1::pi1b; } } namespace nested_name { template int a; // expected-note {{variable template 'a' declared here}} a::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}} class a {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}} enum a {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}} } namespace PR18530 { template int a; int a; // expected-error {{requires 'template<>'}} } namespace PR19152 { #ifndef PRECXX11 template const auto x = 1; static_assert(x == 1, ""); #endif } namespace PR19169 { template int* f(); template void f(); template<> int f; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}} template void g(); template<> int g; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}} } #ifndef PRECXX11 template struct Variadic_t { }; template Variadic_t Variadic; auto variadic1 = Variadic<>; auto variadic2 = Variadic; #endif namespace VexingParse { template int var; // expected-note {{declared here}} int x(var); // expected-error {{cannot refer to variable template 'var' without a template argument list}} }