// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu %s // RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu -std=c++11 %s // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -triple=x86_64-linux-gnu %s -DCPP11ONLY // C++11 [temp.arg.nontype]p1: // // A template-argument for a non-type, non-template template-parameter shall // be one of: // -- an integral constant expression; or // -- the name of a non-type template-parameter ; or #ifndef CPP11ONLY namespace non_type_tmpl_param { template struct X0 { X0(); }; template X0::X0() { } template struct X1 { X1(); }; template X1::X1() { } template struct X3 { X3(); }; template X3::X3() { } template struct X4 { X4(); }; template X4::X4() { } template struct X5 { X5(); }; template X5::X5() { } } // -- a constant expression that designates the address of an object with // static storage duration and external or internal linkage or a function // with external or internal linkage, including function templates and // function template-ids, but excluting non-static class members, expressed // (ignoring parentheses) as & id-expression, except that the & may be // omitted if the name refers to a function or array and shall be omitted // if the corresopnding template-parameter is a reference; or namespace addr_of_obj_or_func { template struct X0 { }; // expected-note 5{{here}} #if __cplusplus >= 201103L // expected-note@-2 2{{template parameter is declared here}} #endif template struct X1 { }; template struct X2 { }; // expected-note 4{{here}} template struct X2k { }; // expected-note {{here}} template struct X3 { }; // expected-note 4{{here}} int i = 42; #if __cplusplus >= 201103L // expected-note@-2 {{declared here}} #endif int iarr[10]; int f(int i); const int ki = 9; #if __cplusplus <= 199711L // expected-note@-2 5{{non-type template argument refers to object here}} #endif __thread int ti = 100; // expected-note {{here}} #if __cplusplus <= 199711L // expected-note@-2 {{here}} #endif static int f_internal(int); #if __cplusplus <= 199711L // expected-note@-2 4{{non-type template argument refers to function here}} #endif template T f_tmpl(T t); struct S { union { int NonStaticMember; }; }; void test() { X0 x0a; #if __cplusplus <= 199711L // expected-error@-2 {{non-type template argument for template parameter of pointer type 'int *' must have its address taken}} #else // expected-error@-4 {{non-type template argument of type 'int' is not a constant expression}} // expected-note@-5 {{read of non-const variable 'i' is not allowed in a constant expression}} #endif X0<&i> x0a_addr; X0 x0b; X0<&iarr> x0b_addr; // expected-error {{cannot be converted to a value of type 'int *'}} X0 x0c; // expected-error {{must have its address taken}} #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X0<&ki> x0c_addr; // expected-error {{cannot be converted to a value of type 'int *'}} #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X0<&ti> x0d_addr; #if __cplusplus <= 199711L // expected-error@-2 {{non-type template argument refers to thread-local object}} #else // expected-error@-4 {{non-type template argument of type 'int *' is not a constant expression}} #endif X1 x1a; X1<&f> x1a_addr; X1 x1b; X1<&f_tmpl> x1b_addr; X1 > x1c; X1<&f_tmpl > x1c_addr; X1 x1d; #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X1<&f_internal> x1d_addr; #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X2 x2a; X2<&i> x2a_addr; // expected-error {{address taken}} X2 x2b; // expected-error {{cannot bind to template argument of type 'int [10]'}} X2<&iarr> x2b_addr; // expected-error {{address taken}} X2 x2c; // expected-error {{ignores qualifiers}} #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X2k x2kc; #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X2k<&ki> x2kc_addr; // expected-error {{address taken}} #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X2 x2d_addr; // expected-error {{refers to thread-local object}} X3 x3a; X3<&f> x3a_addr; // expected-error {{address taken}} X3 x3b; X3<&f_tmpl> x3b_addr; // expected-error {{address taken}} X3 > x3c; X3<&f_tmpl > x3c_addr; // expected-error {{address taken}} X3 x3d; #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif X3<&f_internal> x3d_addr; // expected-error {{address taken}} #if __cplusplus <= 199711L // expected-warning@-2 {{internal linkage is a C++11 extension}} #endif int n; #if __cplusplus <= 199711L // expected-note@-2 {{non-type template argument refers to object here}} #else // expected-note@-4 {{declared here}} #endif X0<&n> x0_no_linkage; #if __cplusplus <= 199711L // expected-error@-2 {{non-type template argument refers to object 'n' that does not have linkage}} #else // expected-error@-4 {{non-type template argument of type 'int *' is not a constant expression}} // expected-note@-5 {{pointer to 'n' is not a constant expression}} #endif struct Local { static int f() {} }; // expected-note {{here}} X1<&Local::f> x1_no_linkage; // expected-error {{non-type template argument refers to function 'f' that does not have linkage}} X0<&S::NonStaticMember> x0_non_static; // expected-error {{non-static data member}} } } // -- a constant expression that evaluates to a null pointer value (4.10); or // -- a constant expression that evaluates to a null member pointer value // (4.11); or // -- a pointer to member expressed as described in 5.3.1. namespace bad_args { template struct X0 { }; // expected-note 2{{template parameter is declared here}} int i = 42; X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}} int* iptr = &i; #if __cplusplus >= 201103L // expected-note@-2 {{declared here}} #endif X0 x0b; #if __cplusplus <= 199711L // expected-error@-2 {{non-type template argument for template parameter of pointer type 'int *' must have its address taken}} #else // expected-error@-4 {{non-type template argument of type 'int *' is not a constant expression}} // expected-note@-5 {{read of non-constexpr variable 'iptr' is not allowed in a constant expression}} #endif } #endif // CPP11ONLY namespace default_args { #ifdef CPP11ONLY namespace lambdas { template //expected-error {{constant expression}} int f(); } #endif // CPP11ONLY }