From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- .../CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp | 60 ++++++ .../test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp | 95 ++++++++++ .../test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp | 205 +++++++++++++++++++++ .../CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp | 40 ++++ .../CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp | 20 ++ clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp | 42 +++++ 6 files changed, 462 insertions(+) create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp (limited to 'clang/test/CXX/temp/temp.arg') diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp new file mode 100644 index 0000000..59ce8b6 --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +namespace std { + typedef decltype(nullptr) nullptr_t; +} + +template struct IP { // expected-note 4 {{template parameter is declared here}} + IP *ip2; +}; + +constexpr std::nullptr_t get_nullptr() { return nullptr; } + +constexpr std::nullptr_t np = nullptr; + +std::nullptr_t nonconst_np; // expected-note{{declared here}} + +IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} +IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} +IP ip2; +IP ip3; +IP<(int*)0> ip4; +IP ip5; +IP ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \ +// expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}} +IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}} + +struct X { }; +template struct PM { // expected-note 2 {{template parameter is declared here}} + PM *pm2; +}; + +PM<0> pm0; // expected-error{{null non-type template argument must be cast to template parameter type 'int X::*'}} +PM<(0)> pm1; // expected-error{{null non-type template argument must be cast to template parameter type 'int X::*'}} +PM pm2; +PM pm3; +PM<(int X::*)0> pm4; +PM pm5; + +template struct PMF { // expected-note 2 {{template parameter is declared here}} + PMF *pmf2; +}; + +PMF<0> pmf0; // expected-error{{null non-type template argument must be cast to template parameter type 'int (X::*)(int)'}} +PMF<(0)> pmf1; // expected-error{{null non-type template argument must be cast to template parameter type 'int (X::*)(int)'}} +PMF pmf2; +PMF pmf3; +PMF<(int (X::*)(int))0> pmf4; +PMF pmf5; + + +template struct NP { // expected-note 2{{template parameter is declared here}} + NP *np2; +}; + +NP np1; +NP np2; +NP np3; +NP<0> np4; // expected-error{{null non-type template argument must be cast to template parameter type 'std::nullptr_t' (aka 'nullptr_t')}} +constexpr int i = 7; +NP np5; // expected-error{{non-type template argument of type 'const int' cannot be converted to a value of type 'std::nullptr_t'}} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp new file mode 100644 index 0000000..c4db002 --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu %s + +// 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 +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 4{{here}} + 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; + int iarr[10]; + int f(int i); + const int ki = 9; // expected-note 5{{here}} + __thread int ti = 100; // expected-note 2{{here}} + static int f_internal(int); // expected-note 4{{here}} + template T f_tmpl(T t); + + void test() { + X0 x0a; // expected-error {{must have its address taken}} + 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}} expected-warning {{internal linkage is a C++11 extension}} + X0<&ki> x0c_addr; // expected-error {{cannot be converted to a value of type 'int *'}} expected-warning {{internal linkage is a C++11 extension}} + X0<&ti> x0d_addr; // expected-error {{refers to thread-local object}} + X1 x1a; + X1<&f> x1a_addr; + X1 x1b; + X1<&f_tmpl> x1b_addr; + X1 > x1c; + X1<&f_tmpl > x1c_addr; + X1 x1d; // expected-warning {{internal linkage is a C++11 extension}} + X1<&f_internal> x1d_addr; // expected-warning {{internal linkage is a C++11 extension}} + 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}} expected-warning {{internal linkage is a C++11 extension}} + X2k x2kc; // expected-warning {{internal linkage is a C++11 extension}} + X2k<&ki> x2kc_addr; // expected-error {{address taken}} expected-warning {{internal linkage is a C++11 extension}} + 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; // expected-warning {{internal linkage is a C++11 extension}} + X3<&f_internal> x3d_addr; // expected-error {{address taken}} expected-warning {{internal linkage is a C++11 extension}} + + int n; // expected-note {{here}} + X0<&n> x0_no_linkage; // expected-error {{non-type template argument refers to object 'n' that does not have linkage}} + 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}} + } +} + +// -- 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; + X0 x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}} +} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp new file mode 100644 index 0000000..9b9b532 --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -0,0 +1,205 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [temp.arg.nontype] p5: +// The following conversions are performed on each expression used as +// a non-type template-argument. If a non-type template-argument cannot be +// converted to the type of the corresponding template-parameter then the +// program is ill-formed. +// -- for a non-type template-parameter of integral or enumeration type, +// integral promotions (4.5) and integral conversions (4.7) are applied. +namespace integral_parameters { + template struct X0 { }; + X0<17> x0i; + X0<'a'> x0c; + template struct X1 { }; + X1<100l> x1l; +} + +// -- for a non-type template-parameter of type pointer to object, +// qualification conversions (4.4) and the array-to-pointer conversion +// (4.2) are applied; if the template-argument is of type +// std::nullptr_t, the null pointer conversion (4.10) is applied. +namespace pointer_to_object_parameters { + // PR6226 + struct Str { + Str(const char *); + }; + + template + struct A { + Str get() { return s; } + }; + + char hello[6] = "Hello"; + extern const char world[6]; + const char world[6] = "world"; + void test() { + (void)A().get(); + (void)A().get(); + } + + class X { + public: + X(); + X(int, int); + operator int() const; + }; + + template struct A2; // expected-note{{template parameter is declared here}} + + X *X_ptr; + X an_X; + X array_of_Xs[10]; + A2 *a12; // expected-error{{must have its address taken}} + A2 *a13; + A2<&an_X> *a13_2; + A2<(&an_X)> *a13_3; // expected-warning{{address non-type template argument cannot be surrounded by parentheses}} + + // PR6244 + struct X1 {} X1v; + template struct X2 { }; + template struct X3 : X2 { }; + struct X4 : X3<&X1v> { }; + + // PR6563 + int *bar; + template struct zed {}; // expected-note 2{{template parameter is declared here}} + void g(zed*); // expected-error{{must have its address taken}} + + int baz; + void g2(zed*); // expected-error{{must have its address taken}} + + void g3(zed<&baz>*); // okay +} + +// -- For a non-type template-parameter of type reference to object, no +// conversions apply. The type referred to by the reference may be more +// cv-qualified than the (otherwise identical) type of the +// template-argument. The template-parameter is bound directly to the +// template-argument, which shall be an lvalue. +namespace reference_parameters { + template struct S0 { }; // expected-note 3 {{template parameter is declared here}} + template struct S1 { }; // expected-note 2 {{template parameter is declared here}} + template struct S2 { }; // expected-note 2 {{template parameter is declared here}} + template struct S3 { }; + int i; + extern const int ci; + volatile int vi; + extern const volatile int cvi; + void test() { + S0 s0; + S0 s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const int' ignores qualifiers}} + S0 s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'volatile int' ignores qualifiers}} + S0 s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const volatile int' ignores qualifiers}} + + S1 s1; + S1 s1c; + S1 s1v; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'volatile int' ignores qualifiers}} + S1 s1cv; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'const volatile int' ignores qualifiers}} + + S2 s2; + S2 s2c; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const int' ignores qualifiers}} + S2 s2v; + S2 s2cv; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const volatile int' ignores qualifiers}} + + S3 s3; + S3 s3c; + S3 s3v; + S3 s3cv; + } + + namespace PR6250 { + template void inc() { + ref++; // expected-error{{read-only variable is not assignable}} + } + + template void bind() { + T &ref2 = ref; // expected-error{{drops qualifiers}} + } + + int counter; + void test() { + inc(); // expected-note{{instantiation of}} + bind(); // expected-note{{instantiation of}} + } + } + + namespace PR6749 { + template struct foo {}; // expected-note{{template parameter is declared here}} + int x, &y = x; + foo f; // expected-error{{is not an object}} + } +} + +// -- For a non-type template-parameter of type pointer to function, the +// function-to-pointer conversion (4.3) is applied; if the +// template-argument is of type std::nullptr_t, the null pointer +// conversion (4.10) is applied. If the template-argument represents +// a set of overloaded functions (or a pointer to such), the matching +// function is selected from the set (13.4). +namespace pointer_to_function { + template struct X0 { }; // expected-note 3{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0); + void x0b(X0<&f>); + void x0c(X0); // expected-error{{non-type template argument of type 'int (float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0d(X0<&g>); // expected-error{{non-type template argument of type 'int (*)(float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0e(X0); // expected-error{{must have its address taken}} +} + +// -- For a non-type template-parameter of type reference to function, no +// conversions apply. If the template-argument represents a set of +// overloaded functions, the matching function is selected from the set +// (13.4). +namespace reference_to_function { + template struct X0 { }; // expected-note 4{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0); + void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0c(X0); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}} + void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0e(X0); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}} +} +// -- For a non-type template-parameter of type pointer to member function, +// if the template-argument is of type std::nullptr_t, the null member +// pointer conversion (4.11) is applied; otherwise, no conversions +// apply. If the template-argument represents a set of overloaded member +// functions, the matching member function is selected from the set +// (13.4). +namespace pointer_to_member_function { + struct X { }; + struct Y : X { + int f(int); + int g(int); + int g(float); + float h(float); + }; + + template struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::f> x0a; + X0<&Y::g> x0b; + X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}} +} + +// -- For a non-type template-parameter of type pointer to data member, +// qualification conversions (4.4) are applied; if the template-argument +// is of type std::nullptr_t, the null member pointer conversion (4.11) +// is applied. +namespace pointer_to_member_data { + struct X { int x; }; + struct Y : X { int y; }; + + template struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::y> x0a; + X0<&Y::x> x0b; // expected-error{{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}} + + // Test qualification conversions + template struct X1 {}; + X1<&Y::y> x1a; +} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp new file mode 100644 index 0000000..1c13bff --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template struct eval; // expected-note 3{{template is declared here}} + +template