diff options
Diffstat (limited to 'test/CXX')
48 files changed, 1415 insertions, 98 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp index 0c905fb..cee7c02 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp @@ -17,7 +17,7 @@ namespace M { struct Y : N::X { }; } -void f(); +void f(); // expected-note 2 {{'f' declared here}} void test_operator_adl(N::X x, M::Y y) { (void)(x + x); diff --git a/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp b/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp new file mode 100644 index 0000000..d930f97 --- /dev/null +++ b/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +void f() { + int b; + int arr[] = {1, 2, 3}; + + if (bool b = true) // expected-note 2{{previous definition}} + bool b; // expected-error {{redefinition}} + else + int b; // expected-error {{redefinition}} + while (bool b = true) // expected-note {{previous definition}} + int b; // expected-error {{redefinition}} + for (int c; // expected-note 2{{previous definition}} + bool c = true;) // expected-error {{redefinition}} + double c; // expected-error {{redefinition}} + switch (int n = 37 + 5) // expected-note {{previous definition}} + int n; // expected-error {{redefinition}} + for (int a : arr) // expected-note {{previous definition}} + int a = 0; // expected-error {{redefinition}} + + if (bool b = true) { // expected-note 2{{previous definition}} + int b; // expected-error {{redefinition}} + } else { + int b; // expected-error {{redefinition}} + } + while (bool b = true) { // expected-note {{previous definition}} + int b; // expected-error {{redefinition}} + } + for (int c; // expected-note 2{{previous definition}} + bool c = true;) { // expected-error {{redefinition}} + double c; // expected-error {{redefinition}} + } + switch (int n = 37 + 5) { // expected-note {{previous definition}} + int n; // expected-error {{redefinition}} + } + for (int &a : arr) { // expected-note {{previous definition}} + int a = 0; // expected-error {{redefinition}} + } + + if (bool b = true) {{ // expected-note {{previous definition}} + bool b; + }} else { + int b; // expected-error {{redefinition}} + } + if (bool b = true) { // expected-note {{previous definition}} + bool b; // expected-error {{redefinition}} + } else {{ + int b; + }} + if (bool b = true) {{ + bool b; + }} else {{ + int b; + }} + while (bool b = true) {{ + int b; + }} + for (int c; // expected-note {{previous definition}} + bool c = true; ) {{ // expected-error {{redefinition}} + double c; + }} + switch (int n = 37 + 5) {{ + int n; + }} + for (int &a : arr) {{ + int a = 0; + }} +} diff --git a/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp b/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp new file mode 100644 index 0000000..751c0df --- /dev/null +++ b/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +// Classes. +namespace Class { + namespace NS { + class C {}; // expected-note {{candidate}} + } + using namespace NS; + class C : C {}; // expected-error {{reference to 'C' is ambiguous}} \ + expected-note {{candidate}} +} + +// Enumerations. +enum E { + EPtrSize = sizeof((E*)0) // ok, E is already declared +}; + +// Alias declarations. clang implements the proposed resolution to N1044. +namespace Alias { + namespace NS { + class C; + } + using namespace NS; + using C = C; // ok, C = B::C + using C = NS::C; // ok, same type +} diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp index 37a4f97..47b5158 100644 --- a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fexceptions -verify %s +// RUN: %clang_cc1 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s int *use_new(int N) { if (N == 1) return new int; diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 84b7b19..4228a44 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s // C++0x [class.access]p4: diff --git a/test/CXX/class.derived/p8-0x.cpp b/test/CXX/class.derived/p8-0x.cpp deleted file mode 100644 index 6a667f7..0000000 --- a/test/CXX/class.derived/p8-0x.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++0x - -namespace Test1 { - -struct A { - virtual void f(); // expected-note {{overridden virtual function is here}} -}; - -struct B explicit : A { - virtual void f(); // expected-error {{overrides function without being marked 'override'}} -}; - -struct C { - virtual ~C(); -}; - -struct D explicit : C { - virtual ~D(); -}; - -} - diff --git a/test/CXX/class/class.mem/p2.cpp b/test/CXX/class/class.mem/p2.cpp new file mode 100644 index 0000000..09040d8 --- /dev/null +++ b/test/CXX/class/class.mem/p2.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++11 [class.mem]p2: +// A class is considered a completely-defined object type (or +// complete type) at the closing } of the class-specifier. Within +// the class member-specification, the class is regarded as complete +// within function bodies, default arguments, +// exception-specifications, and brace-or-equal-initializers for +// non-static data members (including such things in nested classes). +// Otherwise it is regarded as incomplete within its own class +// member-specification. + +namespace test0 { + struct A { // expected-note {{definition of 'test0::A' is not complete until the closing '}'}} + A x; // expected-error {{field has incomplete type 'test0::A'}} + }; +} + +namespace test1 { + template <class T> struct A { + A<int> x; // expected-error {{implicit instantiation of template 'test1::A<int>' within its own definition}} + }; +} + +namespace test2 { + template <class T> struct A; + template <> struct A<int> {}; + template <class T> struct A { + A<int> x; + }; +} diff --git a/test/CXX/class/class.mem/p8-0x-pedantic.cpp b/test/CXX/class/class.mem/p8-0x-pedantic.cpp deleted file mode 100644 index a4b775c..0000000 --- a/test/CXX/class/class.mem/p8-0x-pedantic.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++0x -pedantic -verify %s - -namespace inline_extension { - struct Base1 { - virtual void f() {} - }; - - struct B : Base1 { - virtual void f() override {} // expected-warning {{'override' keyword only allowed in declarations, allowed as an extension}} - virtual void g() final {} // expected-warning {{'final' keyword only allowed in declarations, allowed as an extension}} - virtual void h() new {} // expected-warning {{'new' keyword only allowed in declarations, allowed as an extension}} - }; -} - diff --git a/test/CXX/class/class.mem/p8-0x.cpp b/test/CXX/class/class.mem/p8-0x.cpp index bf1b4c1..836ebad 100644 --- a/test/CXX/class/class.mem/p8-0x.cpp +++ b/test/CXX/class/class.mem/p8-0x.cpp @@ -5,7 +5,6 @@ struct Base1 { }; struct A : Base1 { - virtual void f() new new; // expected-error {{class member already marked 'new'}} virtual void g() override override; // expected-error {{class member already marked 'override'}} virtual void h() final final; // expected-error {{class member already marked 'final'}} }; @@ -34,7 +33,6 @@ namespace inline_extension { }; struct A : Base1 { - virtual void f() new new {} // expected-error {{class member already marked 'new'}} virtual void g() override override {} // expected-error {{class member already marked 'override'}} virtual void h() final final {} // expected-error {{class member already marked 'final'}} }; diff --git a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp index c81e4ef..9116e71 100644 --- a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp +++ b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp @@ -35,17 +35,22 @@ namespace test1 { struct A { void foo(Opaque1); // expected-note {{candidate}} void foo(Opaque2); // expected-note {{candidate}} - void test(); }; struct B : A { - + void test(); }; - void A::test() { - B::foo(Opaque1()); - B::foo(Opaque2()); - B::foo(Opaque3()); // expected-error {{no matching member function}} + struct C1 : A { }; + struct C2 : B { }; + + void B::test() { + A::foo(Opaque1()); + A::foo(Opaque2()); + A::foo(Opaque3()); // expected-error {{no matching member function}} + + C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}} + C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}} } } diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp index b5dd4df..011185f 100644 --- a/test/CXX/class/class.union/p1.cpp +++ b/test/CXX/class/class.union/p1.cpp @@ -7,30 +7,30 @@ class Okay { }; class Virtual { - virtual void foo() { abort(); } // expected-note 3 {{because type 'Virtual' has a virtual member function}} + virtual void foo() { abort(); } // expected-note 4 {{because type 'Virtual' has a virtual member function}} }; -class VirtualBase : virtual Okay { // expected-note 3 {{because type 'VirtualBase' has a virtual base class}} +class VirtualBase : virtual Okay { // expected-note 4 {{because type 'VirtualBase' has a virtual base class}} }; class Ctor { - Ctor() { abort(); } // expected-note 3 {{because type 'Ctor' has a user-declared constructor}} + Ctor() { abort(); } // expected-note 4 {{because type 'Ctor' has a user-declared constructor}} }; class Ctor2 { Ctor2(); // expected-note 3 {{because type 'Ctor2' has a user-declared constructor}} }; class CopyCtor { - CopyCtor(CopyCtor &cc) { abort(); } // expected-note 3 {{because type 'CopyCtor' has a user-declared copy constructor}} + CopyCtor(CopyCtor &cc) { abort(); } // expected-note 4 {{because type 'CopyCtor' has a user-declared copy constructor}} }; // FIXME: this should eventually trigger on the operator's declaration line -class CopyAssign { // expected-note 3 {{because type 'CopyAssign' has a user-declared copy assignment operator}} +class CopyAssign { // expected-note 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}} CopyAssign& operator=(CopyAssign& CA) { abort(); } }; class Dtor { - ~Dtor() { abort(); } // expected-note 3 {{because type 'Dtor' has a user-declared destructor}} + ~Dtor() { abort(); } // expected-note 4 {{because type 'Dtor' has a user-declared destructor}} }; union U1 { @@ -100,23 +100,21 @@ union U5 { template <class A, class B> struct Either { bool tag; - union { + union { // expected-note 6 {{in instantiation of member class}} A a; - B b; + B b; // expected-error 6 {{non-trivial}} }; - Either(A& a) : tag(true), a(a) {} - Either(B& b) : tag(false), b(b) {} + Either(const A& a) : tag(true), a(a) {} + Either(const B& b) : tag(false), b(b) {} }; -/* FIXME: this should work, but crashes in template code. void fred() { - Either<int,Virtual> virt(0); - Either<int,VirtualBase> vbase(0); - Either<int,Ctor> ctor(0); - Either<int,CopyCtor> copyctor(0); - Either<int,CopyAssign> copyassign(0); - Either<int,Dtor> dtor(0); + Either<int,Virtual> virt(0); // expected-note {{in instantiation of template}} + Either<int,VirtualBase> vbase(0); // expected-note {{in instantiation of template}} + Either<int,Ctor> ctor(0); // expected-note {{in instantiation of template}} + Either<int,CopyCtor> copyctor(0); // expected-note {{in instantiation of template}} + Either<int,CopyAssign> copyassign(0); // expected-note {{in instantiation of template}} + Either<int,Dtor> dtor(0); // expected-note {{in instantiation of template}} Either<int,Okay> okay(0); } - */ diff --git a/test/CXX/class/p1-0x.cpp b/test/CXX/class/p1-0x.cpp index 5851de6..e677dec 100644 --- a/test/CXX/class/p1-0x.cpp +++ b/test/CXX/class/p1-0x.cpp @@ -2,9 +2,5 @@ namespace Test1 { class A final { }; -class B explicit { }; -class C final explicit { }; -class D final final { }; // expected-error {{class already marked 'final'}} -class E explicit explicit { }; // expected-error {{class already marked 'explicit'}} } diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp index b9ad6e1..7c4a21c 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp @@ -95,3 +95,24 @@ namespace redecl { inline namespace n1 { }; } } + +// Normal redeclarations (not for explicit instantiations or +// specializations) are distinct in an inline namespace vs. not in an +// inline namespace. +namespace redecl2 { + inline namespace n1 { + void f(int) { } + struct X1 { }; + template<typename T> void f(T) { } + template<typename T> struct X2 { }; + int i = 71; + enum E { e }; + } + + void f(int) { } + struct X1 { }; + template<typename T> void f(T) { } + template<typename T> struct X2 { }; + int i = 71; + enum E { e }; +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp index 15efd72..07eec1e 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp @@ -4,4 +4,4 @@ void f0() { } -inline void f0(); // expected-error {{function definition cannot preceed inline declaration}} +inline void f0(); // expected-error {{function definition cannot precede inline declaration}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp index 18a0cf1..1b1f11a 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s -std=c++0x +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s -std=c++0x struct S { virtual ~S(); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp index fec53c9..09245cf 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s -std=c++0x +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s -std=c++0x struct S { virtual ~S(); @@ -43,8 +43,7 @@ void j() { (void)sizeof(auto); // expected-error{{'auto' not allowed here}} (void)__alignof(auto); // expected-error{{'auto' not allowed here}} - // FIXME: don't issue the second diagnostic for this error. - U<auto> v; // expected-error{{'auto' not allowed in template argument}} unexpected-error{{C++ requires a type specifier}} + U<auto> v; // expected-error{{'auto' not allowed in template argument}} int n; (void)dynamic_cast<auto&>(S()); // expected-error{{'auto' not allowed here}} @@ -63,7 +62,7 @@ enum E : auto {}; // expected-error{{'auto' not allowed here}} struct F : auto {}; // expected-error{{expected class name}} template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed here}} -using A = auto; // expected-error{{expected ';'}} expected-error{{requires a qualified name}} +using A = auto; // expected-error{{'auto' not allowed in type alias}} // FIXME: don't issue the second diagnostic for this error. auto k() -> auto; // expected-error{{'auto' not allowed here}} unexpected-error{{without trailing return type}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp new file mode 100644 index 0000000..10184a0 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// FIXME: when clang supports alias-declarations. +#if 0 +using X = struct { // ok +}; +#endif + +class K { + virtual ~K(); + // FIXME: the diagnostic here isn't very good + operator struct S {} (); // expected-error 2{{}} +}; + +void f() { + int arr[3] = {1,2,3}; + + for (struct S { S(int) {} } s : arr) { // expected-error {{types may not be defined in a for range declaration}} + } + + new struct T {}; // expected-error {{allocation of incomplete type}} expected-note {{forward declaration}} + + // FIXME: the diagnostic here isn't very good + try {} catch (struct U {}); // expected-error 3{{}} expected-note 2{{}} + + (void)(struct V { V(int); })0; // expected-error {{'V' can not be defined in a type specifier}} + + (void)dynamic_cast<struct W {}*>((K*)0); // expected-error {{'W' can not be defined in a type specifier}} + (void)static_cast<struct X {}*>(0); // expected-error {{'X' can not be defined in a type specifier}} + (void)reinterpret_cast<struct Y {}*>(0); // expected-error {{'Y' can not be defined in a type specifier}} + (void)const_cast<struct Z {}*>((const Z*)0); // expected-error {{'Z' can not be defined in a type specifier}} +} + +void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}} +} + +// FIXME: this currently gives a strange error because alignas is not recognised as a keyword yet. +int alignas(struct Aa {}) x; // expected-error {{'Aa' can not be defined in a parameter type}} expected-error {{expected function body}} + +int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}} +int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}} + +namespace std { struct type_info; } +const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' can not be defined in a type specifier}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp new file mode 100644 index 0000000..a51cfbf --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp @@ -0,0 +1,161 @@ +// RUN: %clang_cc1 -verify -std=c++0x %s + +namespace RedeclAliasTypedef { + typedef int T; + using T = int; + using T = int; + typedef T T; + using T = T; + typedef int T; +} + +namespace IllegalTypeIds { + using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}} + using B = inline void(int n); // expected-error {{type name does not allow function specifier}} + using C = virtual void(int n); // expected-error {{type name does not allow function specifier}} + using D = explicit void(int n); // expected-error {{type name does not allow function specifier}} + using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}} + // FIXME: this is illegal; we incorrectly accept it for typedefs too. + using F = void(*)(int n) &&; // expected-err + using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}} + + using H = void(int n); // ok + using I = void(int n) &&; // ok +} + +namespace IllegalSyntax { + using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}} + using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} +} + +namespace VariableLengthArrays { + using T = int[42]; // ok + + int n = 32; + using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}} + + const int m = 42; + using U = int[m]; // expected-note {{previous definition}} + using U = int[42]; // ok + using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}} + + void f() { + int n = 42; + goto foo; // expected-error {{goto into protected scope}} + using T = int[n]; // expected-note {{bypasses initialization of VLA type alias}} + foo: ; + } +} + +namespace RedeclFunc { + int f(int, char**); + using T = int; + T f(int, char **); // ok +} + +namespace LookupFilter { + namespace N { struct S; } + using namespace N; + using S = S*; // ok +} + +namespace InFunctions { + template<typename...T> void f0() { + using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + U u; + } + template void f0<int, char>(); + + void f1() { + using T = int; + } + void f2() { + using T = int[-1]; // expected-error {{array size is negative}} + } + + template<typename...T> void f3() { // expected-note {{template parameter is declared here}} + using T = int; // expected-error {{declaration of 'T' shadows template parameter}} + } +} + +namespace ClassNameRedecl { + class C0 { + // FIXME: this diagnostic is pretty poor + using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}} + }; + class C1 { + // FIXME: this diagnostic is pretty poor + using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}} + }; + class C2 { + using C0 = C1; // ok + }; + template<typename...T> class C3 { + using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + }; + template<typename T> class C4 { // expected-note {{template parameter is declared here}} + using T = int; // expected-error {{declaration of 'T' shadows template parameter}} + }; + class C5 { + class c; // expected-note {{previous definition}} + using c = int; // expected-error {{typedef redefinition with different types}} + class d; + using d = d; // ok + }; + class C6 { + class c { using C6 = int; }; // ok + }; +} + +class CtorDtorName { + using X = CtorDtorName; + X(); // expected-error {{expected member name}} + ~X(); // expected-error {{destructor cannot be declared using a type alias}} +}; + +namespace TagName { + using S = struct { int n; }; + using T = class { int n; }; + using U = enum { a, b, c }; + using V = struct V { int n; }; +} + +namespace CWG1044 { + // FIXME: this is terrible. one error is plenty. + using T = T; // expected-error {{type name requires a specifier}} \ + expected-error {{C++ requires a type specifier}} \ + expected-error {{expected ';' after alias declaration}} +} + +namespace StdExample { + template<typename T, typename U> struct pair; + + using handler_t = void (*)(int); + extern handler_t ignore; + extern void (*ignore)(int); + // FIXME: we know we're parsing a type here; don't recover as if we were + // using operator*. + using cell = pair<void*, cell*>; // expected-error {{use of undeclared identifier 'cell'}} \ + expected-error {{expected expression}} +} + +namespace Access { + class C0 { + using U = int; // expected-note {{declared private here}} + }; + C0::U v; // expected-error {{'U' is a private member}} + class C1 { + public: + using U = int; + }; + C1::U w; // ok +} + +namespace VoidArg { + using V = void; + V f(int); // ok + V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}} +} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp new file mode 100644 index 0000000..3d67fcc --- /dev/null +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +char test1[1]="f"; // expected-error {{initializer-string for char array is too long}} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp index 5fb35ba..868d009 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fcxx-exceptions -fexceptions -verify %s // When it is part of a parameter-declaration-clause, the parameter // pack is a function parameter pack. diff --git a/test/CXX/except/except.handle/p16.cpp b/test/CXX/except/except.handle/p16.cpp index 24f0db0..0810be1 100644 --- a/test/CXX/except/except.handle/p16.cpp +++ b/test/CXX/except/except.handle/p16.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s // The object declared in an exception-declaration or, if the // exception-declaration does not specify a name, a temporary (12.2) diff --git a/test/CXX/except/except.spec/p1.cpp b/test/CXX/except/except.spec/p1.cpp new file mode 100644 index 0000000..0559285 --- /dev/null +++ b/test/CXX/except/except.spec/p1.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Simple parser tests, dynamic specification. + +namespace dyn { + + struct X { }; + + struct Y { }; + + void f() throw() { } + + void g(int) throw(X) { } + + void h() throw(X, Y) { } + + class Class { + void foo() throw (X, Y) { } + }; + + void (*fptr)() throw(); + +} + +// Simple parser tests, noexcept specification. + +namespace noex { + + void f1() noexcept { } + void f2() noexcept (true) { } + void f3() noexcept (false) { } + void f4() noexcept (1 < 2) { } + + class CA1 { + void foo() noexcept { } + void bar() noexcept (true) { } + }; + + void (*fptr1)() noexcept; + void (*fptr2)() noexcept (true); + +} + +namespace mix { + + void f() throw(int) noexcept { } // expected-error {{cannot have both}} + void g() noexcept throw(int) { } // expected-error {{cannot have both}} + +} + +// Sema tests, noexcept specification + +namespace noex { + + struct A {}; + + void g1() noexcept(A()); // expected-error {{not contextually convertible}} + void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} + +} diff --git a/test/CXX/except/except.spec/p11.cpp b/test/CXX/except/except.spec/p11.cpp new file mode 100644 index 0000000..268b53a --- /dev/null +++ b/test/CXX/except/except.spec/p11.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// This is the "let the user shoot himself in the foot" clause. +void f() noexcept { + throw 0; // no-error +} +void g() throw() { + throw 0; // no-error +} +void h() throw(int) { + throw 0.0; // no-error +} diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp index 9450b1c..f5e83ea 100644 --- a/test/CXX/except/except.spec/p14.cpp +++ b/test/CXX/except/except.spec/p14.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -verify %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify %s struct A { }; struct B { }; struct C { }; diff --git a/test/CXX/except/except.spec/p15.cpp b/test/CXX/except/except.spec/p15.cpp new file mode 100644 index 0000000..2dae962 --- /dev/null +++ b/test/CXX/except/except.spec/p15.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Deallocation functions are implicitly noexcept. +// Thus, explicit specs aren't allowed to conflict. + +void f() { + // Force implicit declaration of delete. + delete new int; + delete[] new int[1]; +} + +void operator delete(void*) noexcept; +void operator delete[](void*) noexcept; + +// Same goes for explicit declarations. +void operator delete(void*, float); +void operator delete(void*, float) noexcept; + +void operator delete[](void*, float); +void operator delete[](void*, float) noexcept; + +// But explicit specs stay. +void operator delete(void*, double) throw(int); // expected-note {{previous}} +void operator delete(void*, double) noexcept; // expected-error {{does not match}} diff --git a/test/CXX/except/except.spec/p2-dynamic-types.cpp b/test/CXX/except/except.spec/p2-dynamic-types.cpp new file mode 100644 index 0000000..57f8c32 --- /dev/null +++ b/test/CXX/except/except.spec/p2-dynamic-types.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Dynamic specifications: valid types. + +struct Incomplete; // expected-note 3 {{forward declaration}} + +// Exception spec must not have incomplete types, or pointers to them, except +// void. +void ic1() throw(void); // expected-error {{incomplete type 'void' is not allowed in exception specification}} +void ic2() throw(Incomplete); // expected-error {{incomplete type 'Incomplete' is not allowed in exception specification}} +void ic3() throw(void*); +void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'Incomplete' is not allowed in exception specification}} +void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'Incomplete' is not allowed in exception specification}} + +// Don't suppress errors in template instantiation. +template <typename T> struct TEx; // expected-note {{template is declared here}} + +void tf() throw(TEx<int>); // expected-error {{implicit instantiation of undefined template}} + +// DR 437, class throws itself. +struct DR437 { + void f() throw(DR437); + void g() throw(DR437*); + void h() throw(DR437&); +}; + +// DR 437 within a nested class +struct DR437_out { + struct DR437_in { + void f() throw(DR437_out); + void g() throw(DR437_out*); + void h() throw(DR437_out&); + }; +}; diff --git a/test/CXX/except/except.spec/p2-places.cpp b/test/CXX/except/except.spec/p2-places.cpp new file mode 100644 index 0000000..db1ee77 --- /dev/null +++ b/test/CXX/except/except.spec/p2-places.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Tests where specs are allowed and where they aren't. + +namespace dyn { + + // Straight from the standard: + + // Plain function with spec + void f() throw(int); + + // Pointer to function with spec + void (*fp)() throw (int); + + // Function taking reference to function with spec + void g(void pfa() throw(int)); + + // Typedef for pointer to function with spec + typedef int (*pf)() throw(int); // expected-error {{specifications are not allowed in typedefs}} + + // Some more: + + // Function returning function with spec + void (*h())() throw(int); + + // Ultimate parser thrill: function with spec returning function with spec and + // taking pointer to function with spec. + // The actual function throws int, the return type double, the argument float. + void (*i() throw(int))(void (*)() throw(float)) throw(double); + + // Pointer to pointer to function taking function with spec + void (**k)(void pfa() throw(int)); // no-error + + // Pointer to pointer to function with spec + void (**j)() throw(int); // expected-error {{not allowed beyond a single}} + + // Pointer to function returning pointer to pointer to function with spec + void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}} + +} + +namespace noex { + + // These parallel those from above. + + void f() noexcept(false); + + void (*fp)() noexcept(false); + + void g(void pfa() noexcept(false)); + + typedef int (*pf)() noexcept(false); // expected-error {{specifications are not allowed in typedefs}} + + void (*h())() noexcept(false); + + void (*i() noexcept(false))(void (*)() noexcept(true)) noexcept(false); + + void (**k)(void pfa() noexcept(false)); // no-error + + void (**j)() noexcept(false); // expected-error {{not allowed beyond a single}} + + void (**(*h())())() noexcept(false); // expected-error {{not allowed beyond a single}} +} diff --git a/test/CXX/except/except.spec/p3.cpp b/test/CXX/except/except.spec/p3.cpp new file mode 100644 index 0000000..5df5f26 --- /dev/null +++ b/test/CXX/except/except.spec/p3.cpp @@ -0,0 +1,106 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Exception specification compatibility. +// We test function pointers, because functions have an extra rule in p4. + +// Same type is compatible +extern void (*r1)() throw(int); +extern void (*r1)() throw(int); + +// Typedefs don't matter. +typedef int INT; +extern void (*r2)() throw(int); +extern void (*r2)() throw(INT); + +// Order doesn't matter. +extern void (*r3)() throw(int, float); +extern void (*r3)() throw(float, int); + +// MS throw-any spec and no spec at all are compatible +extern void (*r4)(); +extern void (*r4)() throw(...); + +// throw(X) and no spec are not compatible +extern void (*r5)() throw(int); // expected-note {{previous declaration}} +extern void (*r5)(); // expected-error {{exception specification in declaration does not match}} + +// For functions, we accept this with a warning. +extern void f5() throw(int); // expected-note {{previous declaration}} +extern void f5(); // expected-warning {{missing exception specification}} + +// Different types are not compatible. +extern void (*r7)() throw(int); // expected-note {{previous declaration}} +extern void (*r7)() throw(float); // expected-error {{exception specification in declaration does not match}} + +// Top-level const doesn't matter. +extern void (*r8)() throw(int); +extern void (*r8)() throw(const int); + +// Multiple appearances don't matter. +extern void (*r9)() throw(int, int); +extern void (*r9)() throw(int, int); + + +// noexcept is compatible with itself +extern void (*r10)() noexcept; +extern void (*r10)() noexcept; + +// noexcept(true) is compatible with noexcept +extern void (*r11)() noexcept; +extern void (*r11)() noexcept(true); + +// noexcept(false) isn't +extern void (*r12)() noexcept; // expected-note {{previous declaration}} +extern void (*r12)() noexcept(false); // expected-error {{does not match}} + +// The form of the boolean expression doesn't matter. +extern void (*r13)() noexcept(1 < 2); +extern void (*r13)() noexcept(2 > 1); + +// noexcept(false) is incompatible with noexcept(true) +extern void (*r14)() noexcept(true); // expected-note {{previous declaration}} +extern void (*r14)() noexcept(false); // expected-error {{does not match}} + +// noexcept(false) is compatible with itself +extern void (*r15)() noexcept(false); +extern void (*r15)() noexcept(false); + +// noexcept(false) is compatible with MS throw(...) +extern void (*r16)() noexcept(false); +extern void (*r16)() throw(...); + +// noexcept(false) is *not* compatible with no spec +extern void (*r17)(); // expected-note {{previous declaration}} +extern void (*r17)() noexcept(false); // expected-error {{does not match}} + +// except for functions +void f17(); +void f17() noexcept(false); + +// noexcept(false) is compatible with dynamic specs that throw unless +// CWG 1073 resolution is accepted. Clang implements it. +//extern void (*r18)() throw(int); +//extern void (*r18)() noexcept(false); + +// noexcept(true) is compatible with dynamic specs that don't throw +extern void (*r19)() throw(); +extern void (*r19)() noexcept(true); + +// The other way round doesn't work. +extern void (*r20)() throw(); // expected-note {{previous declaration}} +extern void (*r20)() noexcept(false); // expected-error {{does not match}} + +extern void (*r21)() throw(int); // expected-note {{previous declaration}} +extern void (*r21)() noexcept(true); // expected-error {{does not match}} + + +// As a very special workaround, we allow operator new to match no spec +// with a throw(bad_alloc) spec, because C++0x makes an incompatible change +// here. +extern "C++" { namespace std { class bad_alloc {}; } } +typedef decltype(sizeof(int)) mysize_t; +void* operator new(mysize_t) throw(std::bad_alloc); +void* operator new(mysize_t); +void* operator new[](mysize_t); +void* operator new[](mysize_t) throw(std::bad_alloc); + diff --git a/test/CXX/except/except.spec/p5-pointers.cpp b/test/CXX/except/except.spec/p5-pointers.cpp new file mode 100644 index 0000000..171afff --- /dev/null +++ b/test/CXX/except/except.spec/p5-pointers.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Assignment of function pointers. + +struct A +{ +}; + +struct B1 : A +{ +}; + +struct B2 : A +{ +}; + +struct D : B1, B2 +{ +}; + +struct P : private A +{ +}; + +// Some functions to play with below. +void s1() throw(); +void s2() throw(int); +void s3() throw(A); +void s4() throw(B1); +void s5() throw(D); +void s6(); +void s7() throw(int, float); +void (*s8())() throw(B1); // s8 returns a pointer to function with spec +void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec + +void s10() noexcept; +void s11() noexcept(true); +void s12() noexcept(false); + +void fnptrs() +{ + // Assignment and initialization of function pointers. + void (*t1)() throw() = &s1; // valid + t1 = &s2; // expected-error {{not superset}} expected-error {{incompatible type}} + t1 = &s3; // expected-error {{not superset}} expected-error {{incompatible type}} + void (&t2)() throw() = s2; // expected-error {{not superset}} + void (*t3)() throw(int) = &s2; // valid + void (*t4)() throw(A) = &s1; // valid + t4 = &s3; // valid + t4 = &s4; // valid + t4 = &s5; // expected-error {{not superset}} expected-error {{incompatible type}} + void (*t5)() = &s1; // valid + t5 = &s2; // valid + t5 = &s6; // valid + t5 = &s7; // valid + t1 = t3; // expected-error {{not superset}} expected-error {{incompatible type}} + t3 = t1; // valid + void (*t6)() throw(B1); + t6 = t4; // expected-error {{not superset}} expected-error {{incompatible type}} + t4 = t6; // valid + t5 = t1; // valid + t1 = t5; // expected-error {{not superset}} expected-error {{incompatible type}} + + // return types and arguments must match exactly, no inheritance allowed + void (*(*t7)())() throw(B1) = &s8; // valid + void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}} + void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}} + void (*t10)(void (*)() throw(B1)) = &s9; // valid expected-warning{{disambiguated}} + void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}} + void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}} +} + +// Member function stuff + +struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}} +void Str1::f() // expected-warning {{missing exception specification}} +{ +} + +void mfnptr() +{ + void (Str1::*pfn1)() throw(int) = &Str1::f; // valid + void (Str1::*pfn2)() = &Str1::f; // valid + void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} +} diff --git a/test/CXX/except/except.spec/p5-virtual.cpp b/test/CXX/except/except.spec/p5-virtual.cpp new file mode 100644 index 0000000..ceea9f8 --- /dev/null +++ b/test/CXX/except/except.spec/p5-virtual.cpp @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Compatibility of virtual functions. + +struct A +{ +}; + +struct B1 : A +{ +}; + +struct B2 : A +{ +}; + +struct D : B1, B2 +{ +}; + +struct P : private A +{ +}; + +struct Base +{ + virtual void f1() throw(); + virtual void f2() throw(int, float); + + virtual void f3() throw(int, float); + virtual void f4() throw(A); + virtual void f5() throw(A, int, float); + virtual void f6(); + + virtual void f7() noexcept; + virtual void f8() noexcept; + virtual void f9() noexcept(false); + virtual void f10() noexcept(false); + + virtual void f11() throw(); + virtual void f12() noexcept; + virtual void f13() noexcept(false); + virtual void f14() throw(int); + + virtual void f15(); + virtual void f16(); + + virtual void g1() throw(); // expected-note {{overridden virtual function is here}} + virtual void g2() throw(int); // expected-note {{overridden virtual function is here}} + virtual void g3() throw(A); // expected-note {{overridden virtual function is here}} + virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}} + virtual void g5() throw(A); // expected-note {{overridden virtual function is here}} + + virtual void g6() noexcept; // expected-note {{overridden virtual function is here}} + virtual void g7() noexcept; // expected-note {{overridden virtual function is here}} + + virtual void g8() noexcept; // expected-note {{overridden virtual function is here}} + virtual void g9() throw(); // expected-note {{overridden virtual function is here}} + virtual void g10() throw(int); // expected-note {{overridden virtual function is here}} +}; +struct Derived : Base +{ + virtual void f1() throw(); + virtual void f2() throw(float, int); + + virtual void f3() throw(float); + virtual void f4() throw(B1); + virtual void f5() throw(B1, B2, int); + virtual void f6() throw(B2, B2, int, float, char, double, bool); + + virtual void f7() noexcept; + virtual void f8() noexcept(true); + virtual void f9() noexcept(true); + virtual void f10() noexcept(false); + + virtual void f11() noexcept; + virtual void f12() throw(); + virtual void f13() throw(int); + virtual void f14() noexcept(true); + + virtual void f15() noexcept; + virtual void f16() throw(); + + virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}} + virtual void g2(); // expected-error {{exception specification of overriding function is more lax}} + virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}} + virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}} + virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}} + + virtual void g6() noexcept(false); // expected-error {{exception specification of overriding function is more lax}} + virtual void g7(); // expected-error {{exception specification of overriding function is more lax}} + + virtual void g8() throw(int); // expected-error {{exception specification of overriding function is more lax}} + virtual void g9() noexcept(false); // expected-error {{exception specification of overriding function is more lax}} + virtual void g10() noexcept(false); // expected-error {{exception specification of overriding function is more lax}} +}; diff --git a/test/CXX/except/except.spec/p9-dynamic.cpp b/test/CXX/except/except.spec/p9-dynamic.cpp new file mode 100644 index 0000000..490d2fa --- /dev/null +++ b/test/CXX/except/except.spec/p9-dynamic.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +void external(); + +void target() throw(int) +{ + // CHECK: invoke void @_Z8externalv() + external(); +} +// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* bitcast (i8** @_ZTIi to i8*), i8* null) nounwind +// CHECK: call void @__cxa_call_unexpected diff --git a/test/CXX/except/except.spec/p9-noexcept.cpp b/test/CXX/except/except.spec/p9-noexcept.cpp new file mode 100644 index 0000000..76ac66c --- /dev/null +++ b/test/CXX/except/except.spec/p9-noexcept.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -std=c++0x -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +void external(); + +void target() noexcept +{ + // CHECK: invoke void @_Z8externalv() + external(); +} +// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* null) nounwind +// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind +// CHECK-NEXT: unreachable + +void reverse() noexcept(false) +{ + // CHECK: call void @_Z8externalv() + external(); +} diff --git a/test/CXX/except/except.spec/template.cpp b/test/CXX/except/except.spec/template.cpp new file mode 100644 index 0000000..f8b7270 --- /dev/null +++ b/test/CXX/except/except.spec/template.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// We use pointer assignment compatibility to test instantiation. + +template <int N> void f1() throw(int); +template <int N> void f2() noexcept(N > 1); + +void (*t1)() throw(int) = &f1<0>; +void (*t2)() throw() = &f1<0>; // expected-error {{not superset}} + +void (*t3)() noexcept = &f2<2>; // no-error +void (*t4)() noexcept = &f2<0>; // expected-error {{not superset}} diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp b/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp index 6aec3a2..67d853a 100644 --- a/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++0x -include %S/ser.h %s -o - | FileCheck %s -// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -emit-pch -o %t-ser.pch -std=c++0x -x c++ %S/ser.h -// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++0x -include-pch %t-ser.pch %s -o - | FileCheck %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++0x -include %S/ser.h %s -o - | FileCheck %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-pch -o %t-ser.pch -std=c++0x -x c++ %S/ser.h +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++0x -include-pch %t-ser.pch %s -o - | FileCheck %s struct D { ~D() throw(); diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp index 98c6f4e..28ed62c 100644 --- a/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify -std=c++0x -fms-extensions %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++0x -fms-extensions %s #define P(e) static_assert(noexcept(e), "expected nothrow") #define N(e) static_assert(!noexcept(e), "expected throw") @@ -20,6 +20,8 @@ void allspec() throw(...); void intspec() throw(int); void emptyspec() throw(); void nothrowattr() __attribute__((nothrow)); +void noexcept_true() noexcept; +void noexcept_false() noexcept(false); void call() { N(nospec()); @@ -27,6 +29,8 @@ void call() { N(intspec()); P(emptyspec()); P(nothrowattr()); + P(noexcept_true()); + N(noexcept_false()); } void (*pnospec)(); diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp index 543a86d..30f8c54 100644 --- a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp @@ -29,8 +29,8 @@ bool b8 = !S(); //expected-error {{invalid argument type 'S'}} namespace PR8181 { - void f() { } - void f(char) { } - bool b = !&f; //expected-error {{cannot resolve overloaded function from context}} + void f() { } // expected-note{{candidate function}} + void f(char) { } // expected-note{{candidate function}} + bool b = !&f; //expected-error {{cannot resolve overloaded function 'f' from context}} } diff --git a/test/CXX/lex/lex.pptoken/p3-0x.cpp b/test/CXX/lex/lex.pptoken/p3-0x.cpp new file mode 100644 index 0000000..4ae867c --- /dev/null +++ b/test/CXX/lex/lex.pptoken/p3-0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s + +int a<::> = { 1, 2, 3 }; +int b = a<:::a<:0:>:>; +bool c = a<:0:><::b; + +template<int &n> void f() {} +template void f<::b>(); + +#define x a<:: ## : b :> +int d = x; // expected-error {{pasting formed ':::', an invalid preprocessing token}} expected-error {{expected unqualified-id}} diff --git a/test/CXX/over/over.over/p2-resolve-single-template-id.cpp b/test/CXX/over/over.over/p2-resolve-single-template-id.cpp index f38a74e..544a66d 100644 --- a/test/CXX/over/over.over/p2-resolve-single-template-id.cpp +++ b/test/CXX/over/over.over/p2-resolve-single-template-id.cpp @@ -22,6 +22,36 @@ namespace DontResolveTooEarly_WaitForOverloadResolution } // End namespace +namespace DontAllowUnresolvedOverloadedExpressionInAnUnusedExpression +{ + void one() { } + template<class T> void oneT() { } + + void two() { } //expected-note 2{{candidate}} + void two(int) { } //expected-note 2{{candidate}} + template<class T> void twoT() { } //expected-note 2{{candidate}} + template<class T> void twoT(T) { } //expected-note 2{{candidate}} + + void check() + { + one; // expected-warning {{expression result unused}} + two; // expected-error{{cannot resolve overloaded function 'two' from context}} + oneT<int>; // expected-warning {{expression result unused}} + twoT<int>; // expected-error {{cannot resolve overloaded function 'twoT' from context}} + } + + // check the template function case + template<class T> void check() + { + one; // expected-warning {{expression result unused}} + two; // expected-error{{cannot resolve overloaded function 'two' from context}} + oneT<int>; // expected-warning {{expression result unused}} + twoT<int>; // expected-error {{cannot resolve overloaded function 'twoT' from context}} + + } + +} + template<typename T> void twoT() { } template<typename T, typename U> @@ -45,13 +75,14 @@ namespace DontResolveTooEarly_WaitForOverloadResolution int main() { + { static_cast<void>(one); } { (void)(one); } { static_cast<void>(oneT<int>); } { (void)(oneT<int>); } - { static_cast<void>(two); } // expected-error {{address of overloaded}} - { (void)(two); } // expected-error {{address of overloaded}} + { static_cast<void>(two); } // expected-error {{address of overloaded function 'two' cannot be static_cast to type 'void'}} + { (void)(two); } // expected-error {{address of overloaded function 'two' cannot be cast to type 'void'}} { static_cast<void>(twoT<int>); } { (void)(twoT<int>); } @@ -92,4 +123,69 @@ int main() } - +namespace member_pointers { + struct S { + template <typename T> bool f(T) { return false; } + template <typename T> static bool g(T) { return false; } + + template <typename T> bool h(T) { return false; } + template <int N> static bool h(int) { return false; } + }; + + void test(S s) { + if (S::f<char>) return; // expected-error {{call to non-static member function without an object argument}} + if (S::f<int>) return; // expected-error {{call to non-static member function without an object argument}} + if (&S::f<char>) return; + if (&S::f<int>) return; + if (s.f<char>) return; // expected-error {{a bound member function may only be called}} + if (s.f<int>) return; // expected-error {{a bound member function may only be called}} + if (&s.f<char>) return; // expected-error {{cannot create a non-constant pointer to member function}} + if (&s.f<int>) return; // expected-error {{cannot create a non-constant pointer to member function}} + + if (S::g<char>) return; + if (S::g<int>) return; + if (&S::g<char>) return; + if (&S::g<int>) return; + if (s.g<char>) return; + if (s.g<int>) return; + if (&s.g<char>) return; + if (&s.g<int>) return; + + if (S::h<42>) return; + if (S::h<int>) return; // expected-error {{a bound member function may only be called}} + if (&S::h<42>) return; + if (&S::h<int>) return; + if (s.h<42>) return; + if (s.h<int>) return; // expected-error {{a bound member function may only be called}} + if (&s.h<42>) return; + if (&s.h<int>) return; // expected-error {{a bound member function may only be called}} + + { bool b = S::f<char>; } // expected-error {{call to non-static member function without an object argument}} + { bool b = S::f<int>; } // expected-error {{call to non-static member function without an object argument}} + { bool b = &S::f<char>; } + { bool b = &S::f<int>; } + // These next two errors are terrible. + { bool b = s.f<char>; } // expected-error {{cannot initialize}} + { bool b = s.f<int>; } // expected-error {{cannot initialize}} + { bool b = &s.f<char>; } // expected-error {{cannot create a non-constant pointer to member function}} + { bool b = &s.f<int>; } // expected-error {{cannot create a non-constant pointer to member function}} + + { bool b = S::g<char>; } + { bool b = S::g<int>; } + { bool b = &S::g<char>; } + { bool b = &S::g<int>; } + { bool b = s.g<char>; } + { bool b = s.g<int>; } + { bool b = &s.g<char>; } + { bool b = &s.g<int>; } + + { bool b = S::h<42>; } + { bool b = S::h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}} + { bool b = &S::h<42>; } + { bool b = &S::h<int>; } + { bool b = s.h<42>; } + { bool b = s.h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}} + { bool b = &s.h<42>; } + { bool b = &s.h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}} + } +} diff --git a/test/CXX/special/class.copy/p33-0x.cpp b/test/CXX/special/class.copy/p33-0x.cpp index 262809e..1e6a025 100644 --- a/test/CXX/special/class.copy/p33-0x.cpp +++ b/test/CXX/special/class.copy/p33-0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -std=c++0x -fsyntax-only -verify %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++0x -fsyntax-only -verify %s class X { X(const X&); diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp new file mode 100644 index 0000000..12acde1 --- /dev/null +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +namespace std { + template<typename T> + auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}} + template<typename T> + auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} + + template<typename T> + auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \ + expected-note 4{{candidate template ignored: substitution failure [with T = }} + template<typename T> + auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} + + namespace inner { + // These should never be considered. + int begin(int); + int end(int); + } + + using namespace inner; +} + +struct A { // expected-note {{candidate constructor}} + A(); + int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}} + int *end(); +}; + +struct B { + B(); + int *alt_begin(); + int *alt_end(); +}; + +void f(); // expected-note {{candidate}} +void f(int); // expected-note {{candidate}} + +void g() { + for (int a : A()) + A __begin; + for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} + } + for (char *a : B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} + } + // FIXME: Terrible diagnostic here. auto deduction should fail, but does not! + for (double a : f) { // expected-error {{address of overloaded function 'f' does not match required type '<overloaded function type>'}} + } + for (auto a : A()) { + } + for (auto a : B()) { + } + for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}} + } + // : is not a typo for :: here. + for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'A'}} + } + for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}} + } + + for (auto a : A()) + for (auto b : A()) { + __range.begin(); // expected-error {{use of undeclared identifier '__range'}} + ++__begin; // expected-error {{use of undeclared identifier '__begin'}} + --__end; // expected-error {{use of undeclared identifier '__end'}} + } + + for (char c : "test") + ; + for (auto a : f()) // expected-error {{cannot use type 'void' as a range}} + ; + + extern int incomplete[]; + for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}} + ; + extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}} + for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}} + ; + + struct VoidBegin { + void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}} + void end(); + }; + for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}} + ; + + struct null_t { + operator int*(); + }; + struct Differ { + int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}} + null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}} + }; + for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}} + ; + + for (void f() : "error") // expected-error {{for range declaration must declare a variable}} + ; + + for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}} + for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}} + for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} + // FIXME: when clang supports constexpr, this should be rejected. + for (constexpr int a : A()) {} // desired-error {{loop variable 'a' may not be declared 'constexpr'}} + + struct NoBeginADL { + null_t alt_end(); + }; + struct NoEndADL { + null_t alt_begin(); + }; + for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}} + } + for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}} + } + + struct NoBegin { + null_t end(); + }; + struct NoEnd { + null_t begin(); + }; + for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}} + } + for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} + } + + struct NoIncr { + void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} + void *end(); + }; + for (auto u : NoIncr()) { // expected-error {{arithmetic on pointer to void type}} + } + + struct NoNotEq { + NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}} + NoNotEq end(); + void operator++(); + }; + for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}} + } + + struct NoCopy { + NoCopy(); + NoCopy(const NoCopy &) = delete; + int *begin(); + int *end(); + }; + for (int n : NoCopy()) { // ok + } + + for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \ + expected-note {{range has type 'int'}} + } + + for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}} + } +} + +template<typename T, typename U> +void h(T t) { + for (U u : t) { // expected-error {{no viable conversion from 'A' to 'int'}} + } + for (auto u : t) { + } +} + +template void h<A, int>(A); +template void h<A(&)[4], A &>(A(&)[4]); +template void h<A(&)[13], A>(A(&)[13]); +template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}} + +template<typename T> +void i(T t) { + for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \ + expected-error {{member function 'begin' not viable}} \ + expected-note {{range has type}} + } +} +template void i<A[13]>(A*); // expected-note {{requested here}} +template void i<const A>(const A); // expected-note {{requested here}} + +namespace NS { + class ADL {}; + int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}} + int *end(ADL); + + class NoADL {}; +} +int *begin(NS::NoADL); +int *end(NS::NoADL); + +struct VoidBeginADL {}; +void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}} +void end(VoidBeginADL); + +void j() { + for (auto u : NS::ADL()) { + } + for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}} + } + for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}} + } +} + +void example() { + int array[5] = { 1, 2, 3, 4, 5 }; + for (int &x : array) + x *= 2; +} diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index 2df6d33..cda9ac8 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -216,3 +216,21 @@ namespace ExpandingNonTypeTemplateParameters { tuple_of_values<int&, float&>::apply<i, f, i>::type tv4; // expected-error{{too many template arguments for class template 'apply'}} } + +namespace ExpandingFunctionParameters { + template<typename ...T> + struct X0 { + typedef int type; + }; + + template<typename ...T> + struct X1 { + template<typename ... U> + typename X0<T(T, U...)...>::type f(U...); + }; + + void test() { + X1<float> x1; + x1.f(17, 3.14159); + } +} diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp index e2fa122..7183972 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -fcxx-exceptions -verify %s template<typename... Types> struct tuple; template<int I> struct int_c; diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index 1acc21e..25338e3 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -std=c++0x -fblocks -fms-extensions -fsyntax-only -verify %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++0x -fblocks -fms-extensions -fsyntax-only -verify %s template<typename T, typename U> struct pair; template<typename ...> struct tuple; @@ -205,6 +205,8 @@ struct TestUnexpandedDecls : T{ Types t; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} for (Types *t = 0; ; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} for (; Types *t = 0; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} + T a[] = { T(), T(), T() }; + for (Types t : a) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} switch(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} while(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} if (Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} @@ -341,6 +343,8 @@ void test_unexpanded_exprs(Types ...values) { // SizeOfPackExpr is uninteresting // FIXME: Objective-C expressions will need to go elsewhere + + for (auto t : values) { } // expected-error{{expression contains unexpanded parameter pack 'values'}} } // Test unexpanded parameter packs in partial specializations. diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp index 9ec8f0c..1140aae 100644 --- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp @@ -29,8 +29,8 @@ struct is_same<T, T> { int typeof0[is_same<__typeof__(f<int>), void (int)>::value? 1 : -1]; int typeof1[is_same<__typeof__(&f<int>), void (*)(int)>::value? 1 : -1]; -template <typename T> void g(T); -template <typename T> void g(T, T); +template <typename T> void g(T); // expected-note{{candidate function}} +template <typename T> void g(T, T); // expected-note{{candidate function}} int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \ - // expected-error{{cannot resolve overloaded function from context}} + // expected-error{{cannot resolve overloaded function 'g' from context}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp index ed600e4..4a17cec 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp @@ -237,3 +237,66 @@ void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp, xvp.ft1(vp, i); xvp.ft1(vp, u); } + +namespace has_inline_namespaces { + inline namespace inner { + template<class T> void f(T&); + + template<class T> + struct X0 { + struct MemberClass; + + void mem_func(); + + template<typename U> + struct MemberClassTemplate; + + template<typename U> + void mem_func_template(U&); + + static int value; + }; + } + + struct X1; + struct X2; + + // An explicit specialization whose declarator-id is not qualified + // shall be declared in the nearest enclosing namespace of the + // template, or, if the namespace is inline (7.3.1), any namespace + // from its enclosing namespace set. + template<> void f(X1&); + template<> void f<X2>(X2&); + + template<> struct X0<X1> { }; + + template<> struct X0<X2>::MemberClass { }; + + template<> void X0<X2>::mem_func(); + + template<> template<typename T> struct X0<X2>::MemberClassTemplate { }; + + template<> template<typename T> void X0<X2>::mem_func_template(T&) { } + + template<> int X0<X2>::value = 12; +} + +struct X3; +struct X4; + +template<> void has_inline_namespaces::f(X3&); +template<> void has_inline_namespaces::f<X4>(X4&); + +template<> struct has_inline_namespaces::X0<X3> { }; + +template<> struct has_inline_namespaces::X0<X4>::MemberClass { }; + +template<> void has_inline_namespaces::X0<X4>::mem_func(); + +template<> template<typename T> +struct has_inline_namespaces::X0<X4>::MemberClassTemplate { }; + +template<> template<typename T> +void has_inline_namespaces::X0<X4>::mem_func_template(T&) { } + +template<> int has_inline_namespaces::X0<X4>::value = 13; diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp index 1032a87..2295235 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp @@ -237,3 +237,15 @@ void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp, xvp.ft1(vp, i); xvp.ft1(vp, u); } + +namespace PR8979 { + template<typename Z> + struct X0 { + template <class T, class U> class Inner; + struct OtherInner; + template<typename T, typename U> void f(Inner<T, U>&); + + typedef Inner<OtherInner, OtherInner> MyInner; + template<> void f(MyInner&); // expected-error{{cannot specialize a function 'f' within class scope}} + }; +} diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp index d8f7b52..d0df305 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp @@ -12,16 +12,16 @@ T X<T>::member1; template<typename T> T X<T>::member2 = 17; -// CHECK: @_ZN1XIiE7member1E = weak global i32 0 +// CHECK: @_ZN1XIiE7member1E = weak_odr global i32 0 template int X<int>::member1; -// CHECK: @_ZN1XIiE7member2E = weak global i32 17 +// CHECK: @_ZN1XIiE7member2E = weak_odr global i32 17 template int X<int>::member2; // For implicit instantiation of long& get(bool Cond1, bool Cond2) { - // CHECK: @_ZN1XIlE7member1E = weak global i64 0 - // CHECK: @_ZN1XIlE7member2E = weak global i64 17 + // CHECK: @_ZN1XIlE7member1E = weak_odr global i64 0 + // CHECK: @_ZN1XIlE7member2E = weak_odr global i64 17 // CHECK: @_ZN1XIlE7member3E = external global i64 return Cond1? X<long>::member1 : Cond2? X<long>::member2 diff --git a/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp b/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp new file mode 100644 index 0000000..fdb922a --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -std=c++0x -verify %s + +// If the name declared in the explicit instantiation is an +// unqualified name, the explicit instantiation shall appear in the +// namespace where its template is declared or, if that namespace is +// inline (7.3.1), any namespace from its enclosing namespace set. + +namespace has_inline_namespaces { + inline namespace inner { + template<class T> void f(T&) {} + + template<class T> + struct X0 { + struct MemberClass {}; + + void mem_func() {} + + template<typename U> + struct MemberClassTemplate {}; + + template<typename U> + void mem_func_template(U&) {} + + static int value; + }; + } + + template<typename T> int X0<T>::value = 17; + + struct X1 {}; + struct X2 {}; + + template void f(X1&); + template void f<X2>(X2&); + + template struct X0<X1>; + + template struct X0<X2>::MemberClass; + + template void X0<X2>::mem_func(); + + template struct X0<X2>::MemberClassTemplate<X1>; + + template void X0<X2>::mem_func_template(X1&); + + template int X0<X2>::value; +} + +struct X3; +struct X4; + +template void has_inline_namespaces::f(X3&); +template void has_inline_namespaces::f<X4>(X4&); + +template struct has_inline_namespaces::X0<X3>; + +template struct has_inline_namespaces::X0<X4>::MemberClass; + +template void has_inline_namespaces::X0<X4>::mem_func(); + +template +struct has_inline_namespaces::X0<X4>::MemberClassTemplate<X3>; + +template +void has_inline_namespaces::X0<X4>::mem_func_template(X3&); |