diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
| commit | 56d91b49b13fe55c918afbda19f6165b5fbff87a (patch) | |
| tree | 9abb1a658a297776086f4e0dfa6ca533de02104e /test/CXX | |
| parent | 41e20f564abdb05101d6b2b29c59459a966c22cc (diff) | |
Notes
Diffstat (limited to 'test/CXX')
52 files changed, 1183 insertions, 66 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp new file mode 100644 index 000000000000..f812ea1bd8be --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-show-option -verify %s + +template<typename T> +struct set{}; +struct Value { + template<typename T> + void set(T value) {} + + void resolves_to_same() { + Value v; + v.set<double>(3.2); + } +}; +void resolves_to_different() { + { + Value v; + // The fact that the next line is a warning rather than an error is an + // extension. + v.set<double>(3.2); + } + { + int set; // Non-template. + Value v; + v.set<double>(3.2); + } +} + +namespace rdar9915664 { + struct A { + template<typename T> void a(); + }; + + struct B : A { }; + + struct C : A { }; + + struct D : B, C { + A &getA() { return static_cast<B&>(*this); } + + void test_a() { + getA().a<int>(); + } + }; +} + +namespace PR11856 { + template<typename T> T end(T); + + template <typename T> + void Foo() { + T it1; + if (it1->end < it1->end) { + } + } + + template<typename T> T *end(T*); + + class X { }; + template <typename T> + void Foo2() { + T it1; + if (it1->end < it1->end) { + } + + X *x; + if (x->end < 7) { // expected-error{{no member named 'end' in 'PR11856::X'}} + } + } +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p4-cxx11.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p4-cxx11.cpp new file mode 100644 index 000000000000..792545453e73 --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p4-cxx11.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +struct A { void f(); }; +struct C { void f(); }; +struct B : A { typedef A X; }; +struct D : C { typedef C X; void g(); }; + +void D::g() +{ + B * b = new B; + b->X::f(); // lookup for X finds B::X +} + +typedef int X; +void h(void) +{ + B * b = new B; + b->X::f(); // lookup for X finds B::X +} + + diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp index 83b910b60640..191d42bebd83 100644 --- a/test/CXX/basic/basic.types/p10.cpp +++ b/test/CXX/basic/basic.types/p10.cpp @@ -22,11 +22,11 @@ struct BeingDefined { // (implied) - it is complete -struct Incomplete; +struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}} template<class T> struct ClassTemp {}; -constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} -constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} +constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} expected-note {{incomplete type 'const Incomplete' is not a literal type}} +constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} expected-note {{incomplete type 'Incomplete const[]' is not a literal type}} constexpr ClassTemp<int> classtemplate = {}; constexpr ClassTemp<int> classtemplate2[] = {}; diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 68ff83fee83c..7cb192b5a1f3 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -64,6 +64,7 @@ namespace test0 { }; class MemberFriend { + public: void test(); }; @@ -309,6 +310,7 @@ namespace test10 { // PR8705 namespace test11 { class A { + public: void test0(int); void test1(int); void test2(int); diff --git a/test/CXX/class.access/class.friend/p9-cxx0x.cpp b/test/CXX/class.access/class.friend/p9-cxx0x.cpp new file mode 100644 index 000000000000..f748a2bb3ba6 --- /dev/null +++ b/test/CXX/class.access/class.friend/p9-cxx0x.cpp @@ -0,0 +1,117 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++98 [class.friend]p7: +// C++11 [class.friend]p9: +// A name nominated by a friend declaration shall be accessible in +// the scope of the class containing the friend declaration. + +// PR12328 +// Simple, non-templated case. +namespace test0 { + class X { + void f(); // expected-note {{implicitly declared private here}} + }; + + class Y { + friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test0::X'}} + }; +} + +// Templated but non-dependent. +namespace test1 { + class X { + void f(); // expected-note {{implicitly declared private here}} + }; + + template <class T> class Y { + friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test1::X'}} + }; +} + +// Dependent but instantiated at the right type. +namespace test2 { + template <class T> class Y; + + class X { + void f(); + friend class Y<int>; + }; + + template <class T> class Y { + friend void X::f(); + }; + + template class Y<int>; +} + +// Dependent and instantiated at the wrong type. +namespace test3 { + template <class T> class Y; + + class X { + void f(); // expected-note {{implicitly declared private here}} + friend class Y<int>; + }; + + template <class T> class Y { + friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test3::X'}} + }; + + template class Y<float>; // expected-note {{in instantiation}} +} + +// Dependent because dependently-scoped. +namespace test4 { + template <class T> class X { + void f(); + }; + + template <class T> class Y { + friend void X<T>::f(); + }; +} + +// Dependently-scoped, no friends. +namespace test5 { + template <class T> class X { + void f(); // expected-note {{implicitly declared private here}} + }; + + template <class T> class Y { + friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test5::X<int>'}} + }; + + template class Y<int>; // expected-note {{in instantiation}} +} + +// Dependently-scoped, wrong friend. +namespace test6 { + template <class T> class Y; + + template <class T> class X { + void f(); // expected-note {{implicitly declared private here}} + friend class Y<float>; + }; + + template <class T> class Y { + friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test6::X<int>'}} + }; + + template class Y<int>; // expected-note {{in instantiation}} +} + +// Dependently-scoped, right friend. +namespace test7 { + template <class T> class Y; + + template <class T> class X { + void f(); + friend class Y<int>; + }; + + template <class T> class Y { + friend void X<T>::f(); + }; + + template class Y<int>; +} diff --git a/test/CXX/class.derived/class.virtual/p3-0x.cpp b/test/CXX/class.derived/class.virtual/p3-0x.cpp index c4a401bb27c5..16f98280ed87 100644 --- a/test/CXX/class.derived/class.virtual/p3-0x.cpp +++ b/test/CXX/class.derived/class.virtual/p3-0x.cpp @@ -20,9 +20,15 @@ struct A { template<typename T> struct B : A { + // FIXME: Diagnose this. virtual void f(T) override; }; +template<typename T> +struct C : A { + virtual void f(int) override; // expected-error {{does not override}} +}; + } namespace Test3 { @@ -51,3 +57,46 @@ struct D : B { }; } + +namespace PR13499 { + struct X { + virtual void f(); + virtual void h(); + }; + template<typename T> struct A : X { + void f() override; + void h() final; + }; + template<typename T> struct B : X { + void g() override; // expected-error {{only virtual member functions can be marked 'override'}} + void i() final; // expected-error {{only virtual member functions can be marked 'final'}} + }; + B<int> b; // no-note + template<typename T> struct C : T { + void g() override; + void i() final; + }; + template<typename T> struct D : X { + virtual void g() override; // expected-error {{does not override}} + virtual void i() final; + }; + template<typename...T> struct E : X { + void f(T...) override; + void g(T...) override; // expected-error {{only virtual member functions can be marked 'override'}} + void h(T...) final; + void i(T...) final; // expected-error {{only virtual member functions can be marked 'final'}} + }; + // FIXME: Diagnose these in the template definition, not in the instantiation. + E<> e; // expected-note {{in instantiation of}} + + template<typename T> struct Y : T { + void f() override; + void h() final; + }; + template<typename T> struct Z : T { + void g() override; // expected-error {{only virtual member functions can be marked 'override'}} + void i() final; // expected-error {{only virtual member functions can be marked 'final'}} + }; + Y<X> y; + Z<X> z; // expected-note {{in instantiation of}} +} diff --git a/test/CXX/class/class.mem/p14.cpp b/test/CXX/class/class.mem/p14.cpp index 72b232e8f715..3f14099ef896 100644 --- a/test/CXX/class/class.mem/p14.cpp +++ b/test/CXX/class/class.mem/p14.cpp @@ -9,8 +9,9 @@ struct X0 { }; struct X1 { - int X1; - X1(); // expected-error{{declarator requires an identifier}} + int X1; // expected-note{{hidden by a non-type declaration of 'X1' here}} + X1(); // expected-error{{must use 'struct' tag to refer to type 'X1' in this scope}} \ + // expected-error{{expected member name or ';' after declaration specifiers}} }; struct X2 { diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp index f344ae5b01fb..ee97410aebfe 100644 --- a/test/CXX/class/class.union/p1.cpp +++ b/test/CXX/class/class.union/p1.cpp @@ -27,9 +27,8 @@ class CopyCtor { 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 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}} - CopyAssign& operator=(CopyAssign& CA) { abort(); } +class CopyAssign { + CopyAssign& operator=(CopyAssign& CA) { abort(); } // expected-note 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}} }; class Dtor { diff --git a/test/CXX/class/p6-0x.cpp b/test/CXX/class/p6-0x.cpp index f2cf48282112..e153b4daaf3c 100644 --- a/test/CXX/class/p6-0x.cpp +++ b/test/CXX/class/p6-0x.cpp @@ -19,7 +19,7 @@ struct Trivial2 { Trivial2(const Trivial2 &) = default; Trivial2(Trivial2 &&) = default; Trivial2 &operator=(const Trivial2 &) = default; - Trivial2 &operator=(Trivial2 &) = default; + Trivial2 &operator=(Trivial2 &&) = default; ~Trivial2() = default; }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp index 65573c753362..dfc1d3d04bf9 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -209,7 +209,7 @@ struct ConstexprBaseMemberCtors : Literal { {} }; -// - every assignment-expression that is an initializer-caluse appearing +// - every assignment-expression that is an initializer-clause appearing // directly or indirectly within a brace-or-equal-initializer for a non-static // data member that is not named by a mem-initializer-id shall be a constant // expression; and @@ -224,6 +224,25 @@ struct X { constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1 }; +union XU1 { int a; constexpr XU1() = default; }; // expected-error{{not constexpr}} +union XU2 { int a = 1; constexpr XU2() = default; }; + +struct XU3 { + union { + int a; + }; + constexpr XU3() = default; // expected-error{{not constexpr}} +}; +struct XU4 { + union { + int a = 1; + }; + constexpr XU4() = default; +}; + +static_assert(XU2().a == 1, ""); +static_assert(XU4().a == 1, ""); + // - every implicit conversion used in converting a constructor argument to the // corresponding parameter type and converting a full-expression to the // corresponding member type shall be one of those allowed in a constant @@ -247,3 +266,30 @@ namespace StdExample { int val; }; } + +namespace CtorLookup { + // Ensure that we look up which constructor will actually be used. + struct A { + constexpr A(const A&) {} + A(A&) {} + constexpr A(int); // expected-note {{previous}} + }; + constexpr A::A(int = 0) {} // expected-warning {{default constructor}} + + struct B : A { + B() = default; + constexpr B(const B&); + constexpr B(B&); + }; + constexpr B::B(const B&) = default; + constexpr B::B(B&) = default; // expected-error {{not constexpr}} + + struct C { + A a; + C() = default; + constexpr C(const C&); + constexpr C(C&); + }; + constexpr C::C(const C&) = default; + constexpr C::C(C&) = default; // expected-error {{not constexpr}} +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp index 1daf02f6ea51..f732255a8a4f 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp @@ -49,3 +49,40 @@ void p3example() { same<__typeof(u), const int> uHasTypeConstInt; same<__typeof(y), double> yHasTypeDouble; } + +#if __cplusplus >= 201103L +namespace PR13293 { + // Ensure that dependent declarators have their deduction delayed. + int f(char); + double f(short); + template<typename T> struct S { + static constexpr auto (*p)(T) = &f; + }; + + constexpr int (*f1)(char) = &f; + constexpr double (*f2)(short) = &f; + static_assert(S<char>::p == f1, ""); + static_assert(S<short>::p == f2, ""); + + struct K { int n; }; + template<typename T> struct U { + static constexpr auto (T::*p) = &K::n; + }; + static_assert(U<K>::p == &K::n, ""); + + template<typename T> + using X = auto(int) -> auto(*)(T) -> auto(*)(char) -> long; + X<double> x; + template<typename T> struct V { + //static constexpr auto (*p)(int) -> auto(*)(T) -> auto(*)(char) = &x; // ill-formed + static constexpr auto (*(*(*p)(int))(T))(char) = &x; // ok + }; + V<double> v; + + int *g(double); + template<typename T> void h() { + new (auto(*)(T)) (&g); + } + template void h<double>(); +} +#endif 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 71f57dcc66e7..7499829185eb 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 @@ -64,5 +64,4 @@ template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed 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 in function return type}} unexpected-error{{without trailing return type}} +auto k() -> auto; // expected-error{{'auto' not allowed in function return type}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp index 2bd5d234ce7f..093bc14d47f1 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp @@ -21,7 +21,7 @@ void r() { class PD { friend struct A; - ~PD(); // expected-note 4{{here}} + ~PD(); // expected-note 5{{here}} public: typedef int n; }; @@ -37,8 +37,14 @@ struct A { }; // Two errors here: one for the decltype, one for the variable. -decltype(PD(), PD()) pd1; // expected-error 2{{private destructor}} -decltype(DD(), DD()) dd1; // expected-error 2{{deleted function}} +decltype( + PD(), // expected-error {{private destructor}} + PD()) pd1; // expected-error {{private destructor}} +decltype(DD(), // expected-error {{deleted function}} + DD()) dd1; // expected-error {{deleted function}} +decltype( + PD(), // expected-error {{temporary of type 'PD' has private destructor}} + 0) pd2; decltype(((13, ((DD())))))::n dd_parens; // ok decltype(((((42)), PD())))::n pd_parens_comma; // ok 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 index b06eb01a7fb5..89a28adcc65c 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp @@ -124,9 +124,7 @@ namespace TagName { } namespace CWG1044 { - // FIXME: this diagnostic isn't ideal. one diagnostic is enough. - using T = T; // expected-error {{type name requires a specifier}} \ - expected-error {{expected ';' after alias declaration}} + using T = T; // expected-error {{unknown type name 'T'}} } namespace StdExample { diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp index 06dd1bb05560..783aba182319 100644 --- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp +++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s // An explicitly-defaulted function may be declared constexpr only if it would // have been implicitly declared as constexpr. @@ -27,7 +27,7 @@ struct S2 { // -- it is implicitly considered to be constexpr if the implicit declaration // would be struct S3 { - S3() = default; // expected-note {{here}} + S3() = default; S3(const S3&) = default; S3(S3&&) = default; constexpr S3(int n) : n(n) {} @@ -36,7 +36,7 @@ struct S3 { constexpr S3 s3a = S3(0); constexpr S3 s3b = s3a; constexpr S3 s3c = S3(); -constexpr S3 s3d; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} +constexpr S3 s3d; // expected-error {{default initialization of an object of const type 'const S3' requires a user-provided default constructor}} struct S4 { S4() = default; @@ -44,7 +44,7 @@ struct S4 { S4(S4&&) = default; // expected-note {{here}} NoCopyMove ncm; }; -constexpr S4 s4a; // ok +constexpr S4 s4a{}; // ok constexpr S4 s4b = S4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} constexpr S4 s4c = s4a; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} @@ -54,3 +54,71 @@ struct S5 { }; constexpr S5::S5() = default; static_assert(S5().m == 4, ""); + + +// An explicitly-defaulted function may have an exception specification only if +// it is compatible with the exception specification on an implicit declaration. +struct E1 { + E1() noexcept = default; + E1(const E1&) noexcept = default; + E1(E1&&) noexcept = default; + E1 &operator=(const E1&) noexcept = default; + E1 &operator=(E1&&) noexcept = default; + ~E1() noexcept = default; +}; +struct E2 { + E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}} + E2(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy constructor does not match the calculated one}} + E2(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move constructor does not match the calculated one}} + E2 &operator=(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy assignment operator does not match the calculated one}} + E2 &operator=(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move assignment operator does not match the calculated one}} + ~E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted destructor does not match the calculated one}} +}; + +// If a function is explicitly defaulted on its first declaration +// -- it is implicitly considered to have the same exception-specification as +// if it had been implicitly declared +struct E3 { + E3() = default; + E3(const E3&) = default; + E3(E3&&) = default; + E3 &operator=(const E3&) = default; + E3 &operator=(E3&&) = default; + ~E3() = default; +}; +E3 e3; +static_assert(noexcept(E3(), E3(E3()), E3(e3), e3 = E3(), e3 = e3), ""); +struct E4 { + E4() noexcept(false); + E4(const E4&) noexcept(false); + E4(E4&&) noexcept(false); + E4 &operator=(const E4&) noexcept(false); + E4 &operator=(E4&&) noexcept(false); + ~E4() noexcept(false); +}; +struct E5 { + E5() = default; + E5(const E5&) = default; + E5(E5&&) = default; + E5 &operator=(const E5&) = default; + E5 &operator=(E5&&) = default; + ~E5() = default; + + E4 e4; +}; +E5 e5; +static_assert(!noexcept(E5()), ""); +static_assert(!noexcept(E5(static_cast<E5&&>(e5))), ""); +static_assert(!noexcept(E5(e5)), ""); +static_assert(!noexcept(e5 = E5()), ""); +static_assert(!noexcept(e5 = e5), ""); + +namespace PR13492 { + struct B { + B() = default; + }; + + void f() { + const B b; // expected-error {{default initialization of an object of const type 'const PR13492::B' requires a user-provided default constructor}} + } +} diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp new file mode 100644 index 000000000000..16fd5e6dbda1 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template<typename> void func(); +template<> void func<int>() = delete; + +template<typename> void func2(); +template<> void func2<int>(); // expected-note {{previous declaration is here}} +template<> void func2<int>() = delete; // expected-error {{deleted definition must be first declaration}} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp index 7764980e34f7..fef3692609fa 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp @@ -72,7 +72,7 @@ struct DefaultedAggr { DefaultedAggr(const DefaultedAggr &) = default; DefaultedAggr(DefaultedAggr &&) = default; DefaultedAggr &operator=(const DefaultedAggr &) = default; - DefaultedAggr &operator=(DefaultedAggr &) = default; + DefaultedAggr &operator=(DefaultedAggr &&) = default; ~DefaultedAggr() = default; }; DefaultedAggr da = { 42 } ; diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp new file mode 100644 index 000000000000..3450003a6e2d --- /dev/null +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp @@ -0,0 +1,113 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace std { + typedef decltype(sizeof(int)) size_t; + + template <typename E> + struct initializer_list + { + const E *p; + size_t n; + initializer_list(const E *p, size_t n) : p(p), n(n) {} + }; + + struct string { + string(const char *); + }; + + template<typename A, typename B> + struct pair { + pair(const A&, const B&); + }; +} + +namespace bullet2 { + double ad[] = { 1, 2.0 }; + int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + + struct S2 { + int m1; + double m2, m3; + }; + + S2 s21 = { 1, 2, 3.0 }; + S2 s22 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + S2 s23 { }; +} + +namespace bullet4_example1 { + struct S { + S(std::initializer_list<double> d) {} + S(std::initializer_list<int> i) {} + S() {} + }; + + S s1 = { 1.0, 2.0, 3.0 }; + S s2 = { 1, 2, 3 }; + S s3 = { }; +} + +namespace bullet4_example2 { + struct Map { + Map(std::initializer_list<std::pair<std::string,int>>) {} + }; + + Map ship = {{"Sophie",14}, {"Surprise",28}}; +} + +namespace bullet4_example3 { + struct S { + S(int, double, double) {} + S() {} + }; + + S s1 = { 1, 2, 3.0 }; + // FIXME: This is an ill-formed narrowing initialization. + S s2 { 1.0, 2, 3 }; + S s3 {}; +} + +namespace bullet5 { + struct S { + S(std::initializer_list<double>) {} + S(const std::string &) {} + }; + + const S& r1 = { 1, 2, 3.0 }; + const S& r2 = { "Spinach" }; + S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet5::S' cannot bind to an initializer list temporary}} + const int& i1 = { 1 }; + const int& i2 = { 1.1 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} + const int (&iar)[2] = { 1, 2 }; +} + +namespace bullet6 { + int x1 {2}; + int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} +} + +namespace bullet7 { + int** pp {}; +} + +namespace bullet8 { + struct A { int i; int j; }; + A a1 { 1, 2 }; + A a2 { 1.2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} + + struct B { + B(std::initializer_list<int> i) {} + }; + B b1 { 1, 2 }; + B b2 { 1, 2.0 }; + + struct C { + C(int i, double j) {} + }; + C c1 = { 1, 2.2 }; + // FIXME: This is an ill-formed narrowing initialization. + C c2 = { 1.1, 2 }; // expected-warning {{implicit conversion}} + + int j { 1 }; + int k { }; +} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index db20ea6426e0..9b1727fd04af 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -167,6 +167,20 @@ void shrink_int() { Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} + + // Negative -> larger unsigned type. + unsigned long long ll1 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}} + unsigned long long ll2 = { 1 }; // OK + unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed from type 'short'}} expected-note {{override}} + unsigned long long ll4 = { us }; // OK + unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed from type 'long long'}} expected-note {{override}} + Agg<unsigned long long> ll6 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}} + Agg<unsigned long long> ll7 = { 18446744073709551615ULL }; // OK + Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{ 18446744073709551616 which cannot be narrowed}} expected-note {{override}} expected-warning {{changes value}} + signed char c = 'x'; + unsigned short usc1 = { c }; // expected-error {{non-constant-expression cannot be narrowed from type 'signed char'}} expected-note {{override}} + unsigned short usc2 = { (signed char)'x' }; // OK + unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}} } // Be sure that type- and value-dependent expressions in templates get the error diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp index d58a12953e0d..4ba75efebbb3 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -22,7 +22,7 @@ struct X3 { X3(); private: - X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}} + X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}} }; // Check for instantiation of default arguments diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp new file mode 100644 index 000000000000..21f71f05419c --- /dev/null +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +// A function that is explicitly defaulted shall +// [...] +// -- not have default arguments +struct DefArg { + static DefArg &&make(); + DefArg(int n = 5) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}} + DefArg(const DefArg &DA = make()) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}} + DefArg(const DefArg &DA, int k = 3) = default; // expected-error {{an explicitly-defaulted copy constructor cannot have default arguments}} + DefArg(DefArg &&DA = make()) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}} + DefArg(DefArg &&DA, int k = 3) = default; // expected-error {{an explicitly-defaulted move constructor cannot have default arguments}} + DefArg &operator=(const DefArg&, int k = 4) = default; // expected-error {{parameter of overloaded 'operator=' cannot have a default argument}} + DefArg &operator=(DefArg&&, int k = 4) = default; // expected-error {{parameter of overloaded 'operator=' cannot have a default argument}} + ~DefArg(int k = 5) = default; // expected-error {{destructor cannot have any parameters}} +}; diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp index a87982906631..9b5ef788974e 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp @@ -14,11 +14,11 @@ namespace move { }; struct AssignmentRet1 { - AssignmentRet1&& operator=(AssignmentRet1&&) = default; // expected-error {{an explicitly-defaulted move assignment operator must return an unqualified lvalue reference to its class type}} + AssignmentRet1&& operator=(AssignmentRet1&&) = default; // expected-error {{explicitly-defaulted move assignment operator must return 'move::AssignmentRet1 &'}} }; struct AssignmentRet2 { - const AssignmentRet2& operator=(AssignmentRet2&&) = default; // expected-error {{an explicitly-defaulted move assignment operator must return an unqualified lvalue reference to its class type}} + const AssignmentRet2& operator=(AssignmentRet2&&) = default; // expected-error {{explicitly-defaulted move assignment operator must return 'move::AssignmentRet2 &'}} }; struct ConstAssignment { @@ -38,22 +38,35 @@ namespace copy { }; struct NonConst { - NonConst(NonConst&) = default; - NonConst& operator=(NonConst&) = default; + NonConst(NonConst&) = default; // expected-error {{must be defaulted outside the class}} + NonConst& operator=(NonConst&) = default; // expected-error {{must be defaulted outside the class}} + }; + + struct NonConst2 { + NonConst2(NonConst2&); + NonConst2& operator=(NonConst2&); + }; + NonConst2::NonConst2(NonConst2&) = default; + NonConst2 &NonConst2::operator=(NonConst2&) = default; + + struct NonConst3 { + NonConst3(NonConst3&) = default; + NonConst3& operator=(NonConst3&) = default; + NonConst nc; }; struct BadConst { - NonConst nc; // makes implicit copy non-const BadConst(const BadConst&) = default; // expected-error {{is const, but}} BadConst& operator=(const BadConst&) = default; // expected-error {{is const, but}} + NonConst nc; // makes implicit copy non-const }; struct AssignmentRet1 { - AssignmentRet1&& operator=(const AssignmentRet1&) = default; // expected-error {{an explicitly-defaulted copy assignment operator must return an unqualified lvalue reference to its class type}} + AssignmentRet1&& operator=(const AssignmentRet1&) = default; // expected-error {{explicitly-defaulted copy assignment operator must return 'copy::AssignmentRet1 &'}} }; struct AssignmentRet2 { - const AssignmentRet2& operator=(const AssignmentRet2&) = default; // expected-error {{an explicitly-defaulted copy assignment operator must return an unqualified lvalue reference to its class type}} + const AssignmentRet2& operator=(const AssignmentRet2&) = default; // expected-error {{explicitly-defaulted copy assignment operator must return 'copy::AssignmentRet2 &'}} }; struct ConstAssignment { diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp index 574a3e7a7934..719aeeddebcc 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp @@ -1,3 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -auto j() -> enum { e3 }; // expected-error{{unnamed enumeration must be a definition}} expected-error {{requires a specifier or qualifier}} expected-error {{without trailing return type}} +// FIXME: We should catch the case of tag with an incomplete type here (which +// will necessarily be ill-formed as a trailing return type for a function +// definition), and recover with a "type cannot be defined in a trailing return +// type" error. +auto j() -> enum { e3 }; // expected-error{{unnamed enumeration must be a definition}} expected-error {{expected a type}} diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp index 8763a7028195..4f50afb54887 100644 --- a/test/CXX/except/except.spec/p14.cpp +++ b/test/CXX/except/except.spec/p14.cpp @@ -39,3 +39,27 @@ struct IC1 { // we cannot currently compute the set of thrown types. static_assert(noexcept(IC0()), "IC0() does not throw"); static_assert(!noexcept(IC1()), "IC1() throws"); + +namespace PR13381 { + struct NoThrowMove { + NoThrowMove(const NoThrowMove &); + NoThrowMove(NoThrowMove &&) noexcept; + NoThrowMove &operator=(const NoThrowMove &); + NoThrowMove &operator=(NoThrowMove &&) noexcept; + }; + struct NoThrowMoveOnly { + NoThrowMoveOnly(NoThrowMoveOnly &&) noexcept; + NoThrowMoveOnly &operator=(NoThrowMoveOnly &&) noexcept; + }; + struct X { + const NoThrowMove a; + NoThrowMoveOnly b; + + static X val(); + static X &ref(); + }; + // These both perform a move, but that copy might throw, because it calls + // NoThrowMove's copy constructor (because PR13381::a is const). + static_assert(!noexcept(X(X::val())), ""); + static_assert(!noexcept(X::ref() = X::val()), ""); +} diff --git a/test/CXX/except/except.spec/p5-pointers.cpp b/test/CXX/except/except.spec/p5-pointers.cpp index dd3c0600ce92..f855520aa24d 100644 --- a/test/CXX/except/except.spec/p5-pointers.cpp +++ b/test/CXX/except/except.spec/p5-pointers.cpp @@ -65,9 +65,9 @@ void fnptrs() 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}} + void (*t10)(void (*)() throw(B1)) = &s9; // valid + void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} + void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} } // Member function stuff diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index 054669ef788d..9e6716d0b8ec 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/test/CXX/expr/expr.const/p2-0x.cpp @@ -131,14 +131,14 @@ namespace IncompleteClassTypeAddr { namespace UndefinedBehavior { void f(int n) { switch (n) { - case (int)4.4e9: // expected-error {{constant expression}} expected-note {{value 4.4E+9 is outside the range of representable values of type 'int'}} + case (int)4.4e9: // expected-error {{constant expression}} expected-note {{value 4.4E+9 is outside the range of representable values of type 'int'}} expected-note {{previous case defined here}} case (int)0x80000000u: // ok case (int)10000000000ll: // expected-note {{here}} case (unsigned int)10000000000ll: // expected-error {{duplicate case value}} case (int)(unsigned)(long long)4.4e9: // ok - case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}} + case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}} expected-error {{duplicate case value '2147483647'}} expected-note {{previous case defined here}} case (int)((float)1e37 / 1e30): // ok - case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type 'half'}} + case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type 'half'}} expected-error {{duplicate case value '2147483647'}} break; } } diff --git a/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp b/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp index 22892a63ab16..212adc8c2bd4 100644 --- a/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp +++ b/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp @@ -10,7 +10,10 @@ template<typename T> T&& xvalue(); void test_classification(char *ptr) { int (&fr0)(int) = reinterpret_cast<int (&&)(int)>(f); int &&ir0 = reinterpret_cast<int &&>(*ptr); - int &&ir1 = reinterpret_cast<int &&>(0); - int &&ir2 = reinterpret_cast<int &&>('a'); + int &&ir1 = reinterpret_cast<int &&>(0); // expected-error {{rvalue to reference type}} + int &&ir2 = reinterpret_cast<int &&>('a'); // expected-error {{rvalue to reference type}} int &&ir3 = reinterpret_cast<int &&>(xvalue<char>()); + // Per DR1268, reinterpret_cast can convert between lvalues and xvalues. + int &ir4 = reinterpret_cast<int &>(xvalue<char>()); + int &&ir5 = reinterpret_cast<int &&>(*ptr); } diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm new file mode 100644 index 000000000000..9f9867106930 --- /dev/null +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -emit-llvm -o - -triple x86_64-apple-darwin11.3 %s | FileCheck %s + +namespace PR12746 { + // CHECK: define zeroext i1 @_ZN7PR127462f1EPi + bool f1(int *x) { + // CHECK: store i8* bitcast (i1 (i8*)* @___ZN7PR127462f1EPi_block_invoke to i8*) + bool (^outer)() = ^ { + auto inner = [&]() -> bool { + return x == 0; + }; + return inner(); + }; + return outer(); + } + + // CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke + // CHECK: call zeroext i1 @"_ZNK7PR127462f132___ZN7PR127462f1EPi_block_invoke3$_0clEv" + + bool f2(int *x) { + auto outer = [&]() -> bool { + bool (^inner)() = ^ { + return x == 0; + }; + return inner(); + }; + return outer(); + } +} + diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm index 0c3fdb2d80eb..0db2bf5646ff 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm @@ -86,3 +86,41 @@ namespace overloading { int &ir = accept_lambda_conv([](int x) { return x + 1; }); } } + +namespace PR13117 { + struct A { + template<typename ... Args> static void f(Args...); + + template<typename ... Args> static void f1() + { + (void)^(Args args) { // expected-error{{block contains unexpanded parameter pack 'Args'}} + }; + } + + template<typename ... Args> static void f2() + { + // FIXME: Allow this. + f( + ^(Args args) // expected-error{{block contains unexpanded parameter pack 'Args'}} + { } + ... // expected-error{{pack expansion does not contain any unexpanded parameter packs}} + ); + } + + template<typename ... Args> static void f3() + { + (void)[](Args args) { // expected-error{{expression contains unexpanded parameter pack 'Args'}} + }; + } + + template<typename ... Args> static void f4() + { + f([](Args args) { } ...); + } + }; + + void g() { + A::f1<int, int>(); + A::f2<int, int>(); + } +} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp index 174db257c891..82fc04a48fb6 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp @@ -9,8 +9,8 @@ void print(T first, Ts... rest) { } template<typename... Ts> -void unsupported(Ts ...values) { - auto unsup = [values] {}; // expected-error{{unexpanded function parameter pack capture is unsupported}} +void unexpanded_capture(Ts ...values) { + auto unexp = [values] {}; // expected-error{{initializer contains unexpanded parameter pack 'values'}} } template<typename... Ts> diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp index d816e1702a6d..f580e7e4c46f 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp @@ -25,7 +25,7 @@ void infer_void_return_type(int i) { struct X { }; X infer_X_return_type(X x) { - return [&x](int y) { // expected-warning{{omitted result type}} + return [&x](int y) { if (y > 0) return X(); else @@ -33,11 +33,11 @@ X infer_X_return_type(X x) { }(5); } -X infer_X_return_type_fail(X x) { - return [x](int y) { // expected-warning{{omitted result type}} +X infer_X_return_type_fail(X x) { + return [x](int y) { if (y > 0) return X(); - else + else return x; // expected-error{{return type 'const X' must match previous return type 'X' when lambda expression has unspecified explicit return type}} }(5); } 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 ac11940c80da..2646264273eb 100644 --- a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp @@ -4,7 +4,7 @@ bool b = !0; -bool b2 = !1.2; +bool b2 = !1.2; //expected-warning{{implicit conversion from 'double' to 'bool' changes value from 1.2 to true}} bool b3 = !4; diff --git a/test/CXX/expr/p10-0x.cpp b/test/CXX/expr/p10-0x.cpp new file mode 100644 index 000000000000..564df8843a57 --- /dev/null +++ b/test/CXX/expr/p10-0x.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-pc-linux-gnu %s -o - -std=c++11 | FileCheck %s + +volatile int g1; +struct S { + volatile int a; +} g2; + +volatile int& refcall(); + +// CHECK: define void @_Z2f1PViPV1S +void f1(volatile int *x, volatile S* s) { + // We should perform the load in these cases. + // CHECK: load volatile i32* + (*x); + // CHECK: load volatile i32* + __extension__ g1; + // CHECK: load volatile i32* + s->a; + // CHECK: load volatile i32* + g2.a; + // CHECK: load volatile i32* + s->*(&S::a); + // CHECK: load volatile i32* + // CHECK: load volatile i32* + x[0], 1 ? x[0] : *x; + + // CHECK: load volatile i32* + // CHECK: load volatile i32* + // CHECK: load volatile i32* + *x ?: *x; + + // CHECK: load volatile i32* + ({ *x; }); + + // CHECK-NOT: load volatile + // CHECK: ret +} + +// CHECK: define void @_Z2f2PVi +// CHECK-NOT: load volatile +// CHECK: ret +void f2(volatile int *x) { + // We shouldn't perform the load in these cases. + refcall(); + 1 ? refcall() : *x; +} diff --git a/test/CXX/special/class.conv/class.conv.ctor/p1.cpp b/test/CXX/special/class.conv/class.conv.ctor/p1.cpp new file mode 100644 index 000000000000..d2add82f420f --- /dev/null +++ b/test/CXX/special/class.conv/class.conv.ctor/p1.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +namespace PR13003 { + struct void_type + { + template <typename Arg0, typename... Args> + void_type(Arg0&&, Args&&...) { } + }; + + struct void_type2 + { + template <typename... Args> + void_type2(Args&&...) { } + }; + + struct atom { }; + + void_type v1 = atom(); + void_type2 v2 = atom(); +} + diff --git a/test/CXX/special/class.copy/implicit-move.cpp b/test/CXX/special/class.copy/implicit-move.cpp index 3e9accfbf6a7..597e327a414d 100644 --- a/test/CXX/special/class.copy/implicit-move.cpp +++ b/test/CXX/special/class.copy/implicit-move.cpp @@ -234,3 +234,10 @@ namespace DR1402 { friend NoMove11 &NoMove11::operator=(NoMove11 &&); // expected-error {{no matching function}} }; } + +namespace PR12625 { + struct X; // expected-note {{forward decl}} + struct Y { + X x; // expected-error {{incomplete}} + } y = Y(); +} diff --git a/test/CXX/special/class.copy/p11.0x.copy.cpp b/test/CXX/special/class.copy/p11.0x.copy.cpp index b2b4f6a87f7c..fab3b9dd7bf1 100644 --- a/test/CXX/special/class.copy/p11.0x.copy.cpp +++ b/test/CXX/special/class.copy/p11.0x.copy.cpp @@ -8,7 +8,7 @@ struct NonTrivial { // -- a variant member with a non-trivial corresponding constructor union DeletedNTVariant { - NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant' is implicitly deleted because field 'NT' has a non-trivial copy constructor}} + NonTrivial NT; // expected-note{{copy constructor of 'DeletedNTVariant' is implicitly deleted because variant field 'NT' has a non-trivial copy constructor}} DeletedNTVariant(); }; DeletedNTVariant DVa; @@ -16,7 +16,7 @@ DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy co struct DeletedNTVariant2 { union { - NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant2' is implicitly deleted because field 'NT' has a non-trivial copy constructor}} + NonTrivial NT; // expected-note{{copy constructor of 'DeletedNTVariant2' is implicitly deleted because variant field 'NT' has a non-trivial copy constructor}} }; DeletedNTVariant2(); }; @@ -119,3 +119,15 @@ struct RValue { }; RValue RVa; RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}} + +namespace PR13381 { + struct S { + S(const S&); + S(const volatile S&) = delete; // expected-note{{deleted here}} + }; + struct T { + volatile S s; // expected-note{{field 's' has a deleted copy constructor}} + }; + T &f(); + T t = f(); // expected-error{{call to implicitly-deleted copy constructor}} +} diff --git a/test/CXX/special/class.copy/p13-0x.cpp b/test/CXX/special/class.copy/p13-0x.cpp index 0a9aa6214594..5d436016a056 100644 --- a/test/CXX/special/class.copy/p13-0x.cpp +++ b/test/CXX/special/class.copy/p13-0x.cpp @@ -58,3 +58,59 @@ struct Constexpr5Base {}; struct Constexpr5 : Constexpr5Base { constexpr Constexpr5() {} }; constexpr Constexpr5 ce5move = Constexpr5(); constexpr Constexpr5 ce5copy = ce5move; + +// An explicitly-defaulted constructor doesn't become constexpr until the end of +// its class. Make sure we note that the class has a constexpr constructor when +// that happens. +namespace PR13052 { + template<typename T> struct S { + S() = default; // expected-note 2{{here}} + S(S&&) = default; + S(const S&) = default; + T t; + }; + + struct U { + U() = default; + U(U&&) = default; + U(const U&) = default; + }; + + struct V { + V(); // expected-note {{here}} + V(V&&) = default; + V(const V&) = default; + }; + + struct W { + W(); // expected-note {{here}} + }; + + static_assert(__is_literal_type(U), ""); + static_assert(!__is_literal_type(V), ""); + static_assert(!__is_literal_type(W), ""); + static_assert(__is_literal_type(S<U>), ""); + static_assert(!__is_literal_type(S<V>), ""); + static_assert(!__is_literal_type(S<W>), ""); + + struct X { + friend constexpr U::U() noexcept; + friend constexpr U::U(U&&) noexcept; + friend constexpr U::U(const U&) noexcept; + friend constexpr V::V(); // expected-error {{follows non-constexpr declaration}} + friend constexpr V::V(V&&) noexcept; + friend constexpr V::V(const V&) noexcept; + friend constexpr W::W(); // expected-error {{follows non-constexpr declaration}} + friend constexpr W::W(W&&) noexcept; + friend constexpr W::W(const W&) noexcept; + friend constexpr S<U>::S() noexcept; + friend constexpr S<U>::S(S<U>&&) noexcept; + friend constexpr S<U>::S(const S<U>&) noexcept; + friend constexpr S<V>::S(); // expected-error {{follows non-constexpr declaration}} + friend constexpr S<V>::S(S<V>&&) noexcept; + friend constexpr S<V>::S(const S<V>&) noexcept; + friend constexpr S<W>::S(); // expected-error {{follows non-constexpr declaration}} + friend constexpr S<W>::S(S<W>&&) noexcept; + friend constexpr S<W>::S(const S<W>&) noexcept; + }; +} diff --git a/test/CXX/special/class.copy/p15-inclass.cpp b/test/CXX/special/class.copy/p15-inclass.cpp index c4f8eafd937c..6cfa94fafad5 100644 --- a/test/CXX/special/class.copy/p15-inclass.cpp +++ b/test/CXX/special/class.copy/p15-inclass.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s namespace PR11418 { struct NonPOD { diff --git a/test/CXX/special/class.copy/p23-cxx11.cpp b/test/CXX/special/class.copy/p23-cxx11.cpp new file mode 100644 index 000000000000..7c04a8201804 --- /dev/null +++ b/test/CXX/special/class.copy/p23-cxx11.cpp @@ -0,0 +1,148 @@ +// RUN: %clang_cc1 -verify %s -std=c++11 + +template<typename T> struct CopyAssign { + static T t; + void test() { + t = t; // expected-error +{{deleted}} + } +}; +template<typename T> struct MoveAssign { + static T t; + void test() { + t = static_cast<T&&>(t); // expected-error +{{deleted}} + } +}; + +struct NonTrivialCopyAssign { + NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &); +}; +struct NonTrivialMoveAssign { + NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&); +}; +struct AmbiguousCopyAssign { + AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &); + AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &); +}; +struct AmbiguousMoveAssign { + AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&); + AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&); +}; +struct DeletedCopyAssign { + DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}} +}; +struct DeletedMoveAssign { + DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}} +}; +class InaccessibleCopyAssign { + InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &); +}; +class InaccessibleMoveAssign { + InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&); +}; + +// A defaulted copy/move assignment operator for class X is defined as deleted +// if X has: + +// -- a variant member with a non-trivial corresponding assignment operator +// and X is a union-like class +struct A1 { + union { + NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}} + }; +}; +template struct CopyAssign<A1>; // expected-note {{here}} + +struct A2 { + A2 &operator=(A2 &&) = default; // expected-note {{here}} + union { + NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}} + }; +}; +template struct MoveAssign<A2>; // expected-note {{here}} + +// -- a non-static const data member of (array of) non-class type +struct B1 { + const int a; // expected-note 2{{field 'a' is of const-qualified type}} +}; +struct B2 { + const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}} +}; +struct B3 { + const void *a[3]; +}; +template struct CopyAssign<B1>; // expected-note {{here}} +template struct MoveAssign<B1>; // expected-note {{here}} +template struct CopyAssign<B2>; // expected-note {{here}} +template struct MoveAssign<B2>; // expected-note {{here}} +template struct CopyAssign<B3>; +template struct MoveAssign<B3>; + +// -- a non-static data member of reference type +struct C1 { + int &a; // expected-note 2{{field 'a' is of reference type 'int &'}} +}; +template struct CopyAssign<C1>; // expected-note {{here}} +template struct MoveAssign<C1>; // expected-note {{here}} + +// -- a non-static data member of class type M that cannot be copied/moved +struct D1 { + AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}} +}; +struct D2 { + D2 &operator=(D2 &&) = default; // expected-note {{here}} + AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}} +}; +struct D3 { + DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}} +}; +struct D4 { + D4 &operator=(D4 &&) = default; // expected-note {{here}} + DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}} +}; +struct D5 { + InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}} +}; +struct D6 { + D6 &operator=(D6 &&) = default; // expected-note {{here}} + InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}} +}; +template struct CopyAssign<D1>; // expected-note {{here}} +template struct MoveAssign<D2>; // expected-note {{here}} +template struct CopyAssign<D3>; // expected-note {{here}} +template struct MoveAssign<D4>; // expected-note {{here}} +template struct CopyAssign<D5>; // expected-note {{here}} +template struct MoveAssign<D6>; // expected-note {{here}} + +// -- a direct or virtual base that cannot be copied/moved +struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}} +struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}} + E2 &operator=(E2 &&) = default; // expected-note {{here}} +}; +struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}} +struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}} + E4 &operator=(E4 &&) = default; // expected-note {{here}} +}; +struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}} +struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}} + E6 &operator=(E6 &&) = default; // expected-note {{here}} +}; +template struct CopyAssign<E1>; // expected-note {{here}} +template struct MoveAssign<E2>; // expected-note {{here}} +template struct CopyAssign<E3>; // expected-note {{here}} +template struct MoveAssign<E4>; // expected-note {{here}} +template struct CopyAssign<E5>; // expected-note {{here}} +template struct MoveAssign<E6>; // expected-note {{here}} + +namespace PR13381 { + struct S { + S &operator=(const S&); + S &operator=(const volatile S&) = delete; // expected-note{{deleted here}} + }; + struct T { + volatile S s; // expected-note{{field 's' has a deleted copy assignment}} + }; + void g() { + T t; + t = T(); // expected-error{{implicitly-deleted copy assignment}} + } +} diff --git a/test/CXX/special/class.copy/p8-cxx11.cpp b/test/CXX/special/class.copy/p8-cxx11.cpp index 02e6cd1c9ab6..a2613f461298 100644 --- a/test/CXX/special/class.copy/p8-cxx11.cpp +++ b/test/CXX/special/class.copy/p8-cxx11.cpp @@ -43,6 +43,6 @@ struct Test { friend C::C(C &); friend D::D(const D &); friend E::E(E &); - friend F::F(const F &); + constexpr friend F::F(const F &); friend G::G(G &); }; diff --git a/test/CXX/special/class.ctor/p5-0x.cpp b/test/CXX/special/class.ctor/p5-0x.cpp index 694ab5b17535..1aaeef282ae7 100644 --- a/test/CXX/special/class.ctor/p5-0x.cpp +++ b/test/CXX/special/class.ctor/p5-0x.cpp @@ -21,7 +21,7 @@ int n; // - X is a union-like class that has a variant member with a non-trivial // default constructor, -union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of union 'Deleted1a' is implicitly deleted because field 'u' has a non-trivial default constructor}} +union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of 'Deleted1a' is implicitly deleted because variant field 'u' has a non-trivial default constructor}} Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}} union NotDeleted1a { DefaultedDefCtor1 nu; }; NotDeleted1a nd1a; @@ -53,7 +53,7 @@ class Deleted3a { const int a; }; // expected-note {{because field 'a' of const- expected-warning {{does not declare any constructor}} \ expected-note {{will never be initialized}} Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}} -class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1' would not be initialized}} +class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1 [42]' would not be initialized}} Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}} class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}} Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}} @@ -77,7 +77,7 @@ NotDeleted3g nd3g; union Deleted4a { const int a; const int b; - const UserProvidedDefCtor c; // expected-note {{because field 'c' has a non-trivial default constructor}} + const UserProvidedDefCtor c; // expected-note {{because variant field 'c' has a non-trivial default constructor}} }; Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}} union NotDeleted4a { const int a; int b; }; diff --git a/test/CXX/special/class.ctor/p6-0x.cpp b/test/CXX/special/class.ctor/p6-0x.cpp index 8c8800f2de45..9860317aa122 100644 --- a/test/CXX/special/class.ctor/p6-0x.cpp +++ b/test/CXX/special/class.ctor/p6-0x.cpp @@ -55,3 +55,42 @@ struct A {}; // expected-note {{here}} struct B { friend A::A(); // expected-error {{non-constexpr declaration of 'A' follows constexpr declaration}} }; + +namespace UnionCtors { + union A { // expected-note {{here}} + int a; + int b; + }; + union B { + int a; + int b = 5; + }; + union C { + int a = 5; + int b; + }; + struct D { + union { + int a = 5; + int b; + }; + union { + int c; + int d = 5; + }; + }; + struct E { // expected-note {{here}} + union { + int a; + int b; + }; + }; + + struct Test { + friend constexpr A::A() noexcept; // expected-error {{follows non-constexpr declaration}} + friend constexpr B::B() noexcept; + friend constexpr C::C() noexcept; + friend constexpr D::D() noexcept; + friend constexpr E::E() noexcept; // expected-error {{follows non-constexpr declaration}} + }; +} diff --git a/test/CXX/special/class.dtor/p5-0x.cpp b/test/CXX/special/class.dtor/p5-0x.cpp index dbfa00444075..0d073cea529e 100644 --- a/test/CXX/special/class.dtor/p5-0x.cpp +++ b/test/CXX/special/class.dtor/p5-0x.cpp @@ -16,25 +16,25 @@ class InaccessibleDtor { // destructor. union A1 { A1(); - NonTrivDtor n; // expected-note {{destructor of union 'A1' is implicitly deleted because field 'n' has a non-trivial destructor}} + NonTrivDtor n; // expected-note {{destructor of 'A1' is implicitly deleted because variant field 'n' has a non-trivial destructor}} }; A1 a1; // expected-error {{deleted function}} struct A2 { A2(); union { - NonTrivDtor n; // expected-note {{because field 'n' has a non-trivial destructor}} + NonTrivDtor n; // expected-note {{because variant field 'n' has a non-trivial destructor}} }; }; A2 a2; // expected-error {{deleted function}} union A3 { A3(); - NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}} + NonTrivDtor n[3]; // expected-note {{because variant field 'n' has a non-trivial destructor}} }; A3 a3; // expected-error {{deleted function}} struct A4 { A4(); union { - NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}} + NonTrivDtor n[3]; // expected-note {{because variant field 'n' has a non-trivial destructor}} }; }; A4 a4; // expected-error {{deleted function}} diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index a45b35f71592..96bb47212274 100644 --- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -1,5 +1,13 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +struct pr12960 { + int begin; + void foo(int x) { + for (int& it : x) { // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type 'int'}} + } + } +}; + namespace std { template<typename T> auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}} @@ -207,3 +215,4 @@ void example() { for (int &x : array) x *= 2; } + diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp index 63f569be0861..640d03d4c96f 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -302,6 +302,7 @@ namespace test14 { }; template <class T> class B { + public: void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}} }; @@ -320,10 +321,12 @@ namespace test15 { }; template <class T> class B { + public: void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}} }; template <> class B<float> { + public: void foo() { return A<float>::foo(); } template <class U> void bar(U u) { (void) A<float>::foo(); 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 21aa24fb522d..485068e6486a 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 @@ -249,3 +249,46 @@ namespace PR10230 { int (&ir3)[3] = s<int>().f<int, float, double>(); } } + +namespace PR13386 { + template<typename...> struct tuple {}; + template<typename...T> + struct S { + template<typename...U> + void f(T &&...t, U &&...u) {} // expected-note {{candidate}} + template<typename...U> + void g(U &&...u, T &&...t) {} // expected-note {{candidate}} + template<typename...U> + void h(tuple<T, U> &&...) {} // expected-note 2{{candidate}} + + template<typename...U> + struct X { + template<typename...V> + void x(tuple<T, U, V> &&...); // expected-error {{different lengths}} + }; + }; + + void test() { + S<>().f(); + S<>().f(0); + S<int>().f(0); + S<int>().f(0, 1); + S<int, int>().f(0); // expected-error {{no matching member function for call}} + + S<>().g(); + S<>().g(0); + S<int>().g(0); + S<int>().g(0, 1); // expected-error {{no matching member function for call}} + S<int>().g<int>(0, 1); + S<int, int>().g(0, 1); + + S<>().h(); + S<>().h(0); // expected-error {{no matching member function for call}} + S<int>().h({}); // expected-error {{no matching member function for call}} + S<int>().h<int>({}); + S<int>().h(tuple<int,int>{}); + S<int, int>().h(tuple<int,int>{}, tuple<int,int>{}); + + S<int, int>::X<char>(); // expected-note {{here}} + } +} diff --git a/test/CXX/temp/temp.names/p3-0x.cpp b/test/CXX/temp/temp.names/p3-0x.cpp new file mode 100644 index 000000000000..85dc75e30199 --- /dev/null +++ b/test/CXX/temp/temp.names/p3-0x.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +template<int i> class X { /* ... */ }; +X< 1>2 > x1; // expected-error{{expected unqualified-id}} +X<(1>2)> x2; // OK +template<class T> class Y { /* ... */ }; +Y<X<1>> x3; // OK, same as Y<X<1> > x3; +Y<X<6>>1>> x4; // expected-error{{expected unqualified-id}} +Y<X<(6>>1)>> x5; + +int a, b; +Y<decltype(a < b)> x6; diff --git a/test/CXX/temp/temp.spec/p5.cpp b/test/CXX/temp/temp.spec/p5.cpp index 0e69a26b04e2..ba92d41e3e8e 100644 --- a/test/CXX/temp/temp.spec/p5.cpp +++ b/test/CXX/temp/temp.spec/p5.cpp @@ -14,7 +14,7 @@ struct X0 { }; template<typename T> -T X0<T>::value = 3.14; // expected-warning{{implicit conversion turns literal floating-point number into integer}} +T X0<T>::value = 3.14; // expected-warning{{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}} template struct X0<int>; // expected-note{{previous explicit instantiation}} \ expected-note{{requested here}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp index 121cb8eedf2f..aba9d3640801 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s template<class T> void f(T) { /* ... */ } template<class T> inline void g(T) { /* ... */ } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp index 84841cb60f4d..c8b7def5a448 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp @@ -1,10 +1,14 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s namespace N { - template<class T> class X; + template<class T> class X; // expected-note {{'N::X' declared here}} \ + // expected-note {{explicitly specialized declaration is here}} } -template<> class X<int> { /* ... */ }; // expected-error {{non-template class 'X'}} +// TODO: Don't add a namespace qualifier to the template if it would trigger +// the warning about the specialization being outside of the namespace. +template<> class X<int> { /* ... */ }; // expected-error {{no template named 'X'; did you mean 'N::X'?}} \ + // expected-warning {{first declaration of class template specialization of 'X' outside namespace 'N' is a C++11 extension}} namespace N { diff --git a/test/CXX/temp/temp.spec/temp.explicit/p12.cpp b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp index c7564868f8ad..9518a0b077b7 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p12.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp @@ -1,6 +1,49 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -char* p = 0; -template<class T> T g(T x = &p) { return x; } -template int g<int>(int); // OK even though &p isn't an int. +namespace test0 { + char* p = 0; + template<class T> T g(T x = &p) { return x; } + template int g<int>(int); // OK even though &p isn't an int. +} +// Don't impose access restrictions on explicit instantiations. +namespace test1 { + class A { + class Private {}; + public: + typedef Private Public; + }; + + template <class T> class Temp { + static Temp<A::Public> make() { return Temp<A::Public>(); } + }; + template class Temp<A::Private>; + + // FIXME: this ought to be an error, but it isn't because Sema is + // silently failing to create a declaration for the explicit + // instantiation. + template class Temp<A::Private> Temp<int>::make(); +} + +// Don't impose access restrictions on explicit specializations, +// either. This goes here because it's an extension of the rule for +// explicit instantiations and doesn't have any independent support. +namespace test2 { + class A { + class Private {}; // expected-note {{implicitly declared private here}} + public: + typedef Private Public; + }; + + template <class T> class Temp { + static Temp<A::Public> make(); + }; + template <> class Temp<A::Private> { + public: + Temp(int x) {} + }; + + template <> class Temp<A::Private> Temp<int>::make() { // expected-error {{'Private' is a private member of 'test2::A'}} + return Temp<A::Public>(0); + } +} diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp index 04e7df5741e2..ff24ad997dfd 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -O1 -emit-llvm -std=c++11 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -emit-llvm -std=c++11 -o - %s | FileCheck %s template<typename T> struct X0 { |
