diff options
Diffstat (limited to 'test/CXX')
19 files changed, 686 insertions, 20 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp index b59e6ca320e0a..df3429ef31c73 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp @@ -40,3 +40,15 @@ namespace Test { D::D() + D::D(); // expected-error {{ invalid operands to binary expression ('D::D' and 'D::D') }} } } + +// PR6716 +namespace test1 { + template <class T> class A { + template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('A<int> const') would lose const qualifier}} + }; + + void test() { + const A<int> a; + foo(a, 10); // expected-error {{no matching function for call to 'foo'}} + } +} diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp new file mode 100644 index 0000000000000..4567c469e817a --- /dev/null +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +namespace std { + class bad_alloc { }; + + typedef __SIZE_TYPE__ size_t; +} + +class foo { virtual ~foo(); }; + +void* operator new(std::size_t); +void* operator new[](std::size_t); +void operator delete(void*); +void operator delete[](void*); 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 f4860bb9babfb..37a4f976badad 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 -verify %s +// RUN: %clang_cc1 -fsyntax-only -fexceptions -verify %s int *use_new(int N) { if (N == 1) return new int; @@ -19,7 +19,10 @@ namespace std { typedef __SIZE_TYPE__ size_t; } -void* operator new(std::size_t) throw(std::bad_alloc); +void* operator new(std::size_t) throw(std::bad_alloc); // expected-note{{previous declaration}} void* operator new[](std::size_t) throw(std::bad_alloc); -void operator delete(void*) throw(); +void operator delete(void*) throw(); // expected-note{{previous declaration}} void operator delete[](void*) throw(); + +void* operator new(std::size_t); // expected-warning{{'operator new' is missing exception specification 'throw(std::bad_alloc)'}} +void operator delete(void*); // expected-warning{{'operator delete' is missing exception specification 'throw()'}} diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp new file mode 100644 index 0000000000000..96037e7de2b04 --- /dev/null +++ b/test/CXX/class.access/class.access.base/p5.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -faccess-control -verify %s + +namespace test0 { + struct A { + static int x; + }; + struct B : A {}; + struct C : B {}; + + int test() { + return A::x + + B::x + + C::x; + } +} + +namespace test1 { + struct A { + private: static int x; // expected-note 5 {{declared private here}} + static int test() { return x; } + }; + struct B : public A { + static int test() { return x; } // expected-error {{private member}} + }; + struct C : private A { + static int test() { return x; } // expected-error {{private member}} + }; + + struct D { + public: static int x; + static int test() { return x; } + }; + struct E : private D { // expected-note{{constrained by private inheritance}} + static int test() { return x; } + }; + + int test() { + return A::x // expected-error {{private member}} + + B::x // expected-error {{private member}} + + C::x // expected-error {{private member}} + + D::x + + E::x; // expected-error {{private member}} + } +} + +namespace test2 { + class A { + protected: static int x; + }; + + class B : private A {}; // expected-note {{private inheritance}} + class C : private A { + int test(B *b) { + return b->x; // expected-error {{private member}} + } + }; +} + +namespace test3 { + class A { + protected: static int x; + }; + + class B : public A {}; + class C : private A { + int test(B *b) { + // x is accessible at C when named in A. + // A is an accessible base of B at C. + // Therefore this succeeds. + return b->x; + } + }; +} + +// TODO: flesh out these cases diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 851cd3d008847..22266cd8f8fcd 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -149,3 +149,46 @@ namespace test2 { // expected-error {{'getNext' is a private member of 'test2::ilist_node'}} }; } + +namespace test3 { + class A { protected: int x; }; // expected-note {{declared protected here}} + + class B : public A { + friend int foo(B*); + }; + + int foo(B *p) { + return p->x; + } + + int foo(const B *p) { + return p->x; // expected-error {{'x' is a protected member of 'test3::A'}} + } +} + +namespace test3a { + class A { protected: int x; }; + + class B : public A { + friend int foo(B*); + }; + + int foo(B * const p) { + return p->x; + } +} + +namespace test4 { + template <class T> class Holder { + T object; + friend bool operator==(Holder &a, Holder &b) { + return a.object == b.object; // expected-error {{invalid operands to binary expression}} + } + }; + + struct Inequal {}; + bool test() { + Holder<Inequal> a, b; + return a == b; // expected-note {{requested here}} + } +} diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index bc69bee657c97..3bbdbab8d516d 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -101,14 +101,14 @@ namespace test2 { namespace test3 { class A { private: - ~A(); // expected-note 3 {{declared private here}} + ~A(); // expected-note 2 {{declared private here}} static A foo; }; A a; // expected-error {{variable of type 'test3::A' has private destructor}} A A::foo; - void foo(A param) { // expected-error {{variable of type 'test3::A' has private destructor}} + void foo(A param) { // okay A local; // expected-error {{variable of type 'test3::A' has private destructor}} } @@ -262,3 +262,68 @@ namespace test9 { static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}} }; } + +namespace test10 { + class A { + enum { + value = 10 // expected-note {{declared private here}} + }; + friend class C; + }; + + class B { + enum { + value = A::value // expected-error {{'value' is a private member of 'test10::A'}} + }; + }; + + class C { + enum { + value = A::value + }; + }; +} + +namespace test11 { + class A { + protected: virtual ~A(); + }; + + class B : public A { + ~B(); + }; + + B::~B() {}; +} + +namespace test12 { + class A { + int x; + + void foo() { + class Local { + int foo(A *a) { + return a->x; + } + }; + } + }; +} + +namespace test13 { + struct A { + int x; + unsigned foo() const; + }; + + struct B : protected A { + using A::foo; + using A::x; + }; + + void test() { + A *d; + d->foo(); + (void) d->x; + } +} diff --git a/test/CXX/class.derived/class.abstract/p4.cpp b/test/CXX/class.derived/class.abstract/p4.cpp new file mode 100644 index 0000000000000..ca99bf7f1658e --- /dev/null +++ b/test/CXX/class.derived/class.abstract/p4.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR6631 { + struct A { + virtual void f() = 0; + }; + + struct B : virtual A { }; + + struct C : virtual A { + virtual void f(); + }; + + struct D : public B, public C { + virtual void f(); + }; + + void f() { + (void)new D; // okay + } +} + +// Check cases where we have a virtual function that is pure in one +// subobject but not pure in another subobject. +namespace PartlyPure { + struct A { + virtual void f() = 0; // expected-note{{pure virtual function}} + }; + + struct B : A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // expected-error{{abstract type}} + } +} + +namespace NonPureAlongOnePath { + struct A { + virtual void f() = 0; + }; + + struct B : virtual A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // okay + } +} + +namespace NonPureAlongOnePath2 { + struct Aprime { + virtual void f() = 0; + }; + + struct A : Aprime { + }; + + struct B : virtual A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // okay + } +} diff --git a/test/CXX/class.derived/class.abstract/p5.cpp b/test/CXX/class.derived/class.abstract/p5.cpp new file mode 100644 index 0000000000000..207519d17e4e7 --- /dev/null +++ b/test/CXX/class.derived/class.abstract/p5.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + virtual void f() = 0; // expected-note{{pure virtual function}} +}; + +struct B : A { + virtual void f(); +}; + +struct C : B { + virtual void f() = 0; // expected-note 2{{pure virtual function}} +}; + +struct D : C { +}; + +void test() { + (void)new A; // expected-error{{object of abstract type}} + (void)new B; + (void)new C; // expected-error{{object of abstract type}} + (void)new D; // expected-error{{object of abstract type}} +} diff --git a/test/CXX/class.derived/class.virtual/p2.cpp b/test/CXX/class.derived/class.virtual/p2.cpp new file mode 100644 index 0000000000000..64d93c8836598 --- /dev/null +++ b/test/CXX/class.derived/class.virtual/p2.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A { + virtual void f() = 0; // expected-note 2{{overridden virtual function}} +}; + +struct Aprime : virtual A { + virtual void f(); +}; + +struct B : Aprime { + virtual void f(); // expected-note 3{{final overrider of 'A::f'}} +}; + +struct C : virtual A { + virtual void f(); // expected-note{{final overrider of 'A::f'}} +}; + +struct D : B, C { }; // expected-error{{virtual function 'A::f' has more than one final overrider in 'D'}} + +struct B2 : B { }; + +struct E : B, B2 { }; //expected-error{{virtual function 'A::f' has more than one final overrider in 'E'}} + +struct F : B, B2 { + virtual void f(); // okay +}; + +struct G : F { }; // okay + +struct H : G, A { }; // okay + +namespace MultipleSubobjects { + struct A { virtual void f(); }; + struct B : A { virtual void f(); }; + struct C : A { virtual void f(); }; + struct D : B, C { }; // okay +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp index 935f5767889fb..89e9c897d2258 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s // We have to avoid ADL for this test. @@ -65,3 +65,44 @@ namespace Test1 { b _2 = B::b(); } } + +namespace test2 { + class A { + protected: + operator int(); + operator bool(); + }; + + class B : private A { + protected: + using A::operator int; // expected-note {{'declared protected here'}} + public: + using A::operator bool; + }; + + int test() { + bool b = B(); + return B(); // expected-error {{'operator int' is a protected member of 'test2::B'}} + } +} + +namespace test3 { + class A { + ~A(); + }; + + class B { + friend class C; + private: + operator A*(); + }; + + class C : public B { + public: + using B::operator A*; + }; + + void test() { + delete C(); + } +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp index 392888e71b45b..c530311773231 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp @@ -25,8 +25,7 @@ template <> class B<int> { }; template <> struct B<A> { - // FIXME: the error here should be associated with the use at "void foo..." - union Member { // expected-note 4 {{previous use is here}} expected-error {{tag type that does not match previous declaration}} + union Member { // expected-note 4 {{previous use is here}} void* a; }; }; @@ -41,10 +40,10 @@ void c2(class B<float>::Member); void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} -void d1(struct B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} -void d2(class B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} -void d3(union B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} -void d4(enum B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}} +void d1(struct B<int>::Member); // expected-error {{no struct named 'Member' in 'B<int>'}} +void d2(class B<int>::Member); // expected-error {{no class named 'Member' in 'B<int>'}} +void d3(union B<int>::Member); // expected-error {{no union named 'Member' in 'B<int>'}} +void d4(enum B<int>::Member); // expected-error {{no enum named 'Member' in 'B<int>'}} void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} @@ -52,7 +51,8 @@ void e3(union B<A>::Member); void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} template <class T> struct C { - void foo(class B<T>::Member); // expected-error{{no type named 'Member' in 'B<int>'}} + void foo(class B<T>::Member); // expected-error{{no class named 'Member' in 'B<int>'}} \ + // expected-error{{use of 'Member' with tag type that does not match previous declaration}} }; C<float> f1; diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp new file mode 100644 index 0000000000000..e674f9708c517 --- /dev/null +++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int f(); + +void g() { + if (int x = f()) { // expected-note 2{{previous definition}} + int x; // expected-error{{redefinition of 'x'}} + } else { + int x; // expected-error{{redefinition of 'x'}} + } +} diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp index 83365a2a082c9..14dace89a156b 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -49,9 +49,9 @@ namespace addr_of_obj_or_func { // -- a pointer to member expressed as described in 5.3.1. namespace bad_args { - template <int* N> struct X0 { }; + template <int* N> struct X0 { }; // expected-note 2{{template parameter is declared here}} int i = 42; X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}} int* iptr = &i; - X0<iptr> x0b; // FIXME: This should not be accepted. + X0<iptr> x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}} } diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp index 458aff2f0232a..b0f1c46a5226a 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -7,6 +7,14 @@ // program is ill-formed. // -- for a non-type template-parameter of integral or enumeration type, // integral promotions (4.5) and integral conversions (4.7) are applied. +namespace integral_parameters { + template<short s> struct X0 { }; + X0<17> x0i; + X0<'a'> x0c; + template<char c> struct X1 { }; + X1<100l> x1l; +} + // -- for a non-type template-parameter of type pointer to object, // qualification conversions (4.4) and the array-to-pointer conversion // (4.2) are applied; if the template-argument is of type @@ -37,12 +45,12 @@ namespace pointer_to_object_parameters { operator int() const; }; - template<X const *Ptr> struct A2; + template<X const *Ptr> struct A2; // expected-note{{template parameter is declared here}} X *X_ptr; X an_X; X array_of_Xs[10]; - A2<X_ptr> *a12; + A2<X_ptr> *a12; // expected-error{{must have its address taken}} A2<array_of_Xs> *a13; A2<&an_X> *a13_2; A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} @@ -52,6 +60,16 @@ namespace pointer_to_object_parameters { template <X1*> struct X2 { }; template <X1* Value> struct X3 : X2<Value> { }; struct X4 : X3<&X1v> { }; + + // PR6563 + int *bar; + template <int *> struct zed {}; // expected-note 2{{template parameter is declared here}} + void g(zed<bar>*); // expected-error{{must have its address taken}} + + int baz; + void g2(zed<baz>*); // expected-error{{must have its address taken}} + + void g3(zed<&baz>*); // okay } // -- For a non-type template-parameter of type reference to object, no @@ -105,6 +123,12 @@ namespace reference_parameters { bind<int, counter>(); // expected-note{{instantiation of}} } } + + namespace PR6749 { + template <int& i> struct foo {}; // expected-note{{template parameter is declared here}} + int x, &y = x; + foo<y> f; // expected-error{{is not an object}} + } } // -- For a non-type template-parameter of type pointer to function, the @@ -113,17 +137,69 @@ namespace reference_parameters { // conversion (4.10) is applied. If the template-argument represents // a set of overloaded functions (or a pointer to such), the matching // function is selected from the set (13.4). +namespace pointer_to_function { + template<int (*)(int)> struct X0 { }; // expected-note 3{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0<f>); + void x0b(X0<&f>); + void x0c(X0<g>); // expected-error{{non-type template argument of type 'int (float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0d(X0<&g>); // expected-error{{non-type template argument of type 'int (*)(float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0e(X0<funcptr>); // expected-error{{must have its address taken}} +} + // -- For a non-type template-parameter of type reference to function, no // conversions apply. If the template-argument represents a set of // overloaded functions, the matching function is selected from the set // (13.4). +namespace reference_to_function { + template<int (&)(int)> struct X0 { }; // expected-note 4{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0<f>); + void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0c(X0<g>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}} + void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0e(X0<funcptr>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}} +} // -- For a non-type template-parameter of type pointer to member function, // if the template-argument is of type std::nullptr_t, the null member // pointer conversion (4.11) is applied; otherwise, no conversions // apply. If the template-argument represents a set of overloaded member // functions, the matching member function is selected from the set // (13.4). +namespace pointer_to_member_function { + struct X { }; + struct Y : X { + int f(int); + int g(int); + int g(float); + float h(float); + }; + + template<int (Y::*)(int)> struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::f> x0a; + X0<&Y::g> x0b; + X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}} +} + // -- For a non-type template-parameter of type pointer to data member, // qualification conversions (4.4) are applied; if the template-argument // is of type std::nullptr_t, the null member pointer conversion (4.11) // is applied. +namespace pointer_to_member_data { + struct X { int x; }; + struct Y : X { int y; }; + + template<int Y::*> struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::y> x0a; + X0<&Y::x> x0b; // expected-error{{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}} + + // Test qualification conversions + template<const int Y::*> struct X1 {}; + X1<&Y::y> x1a; +} diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp index f1b3c814c4261..c9dc5460a0f68 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -faccess-control -verify -emit-llvm-only %s +namespace test0 { template <typename T> struct Num { T value_; @@ -54,6 +55,7 @@ int calc2() { Num<int> result = x * n; return result.get(); } +} // Reduced from GNU <locale> namespace test1 { @@ -85,3 +87,132 @@ namespace test2 { } }; } + +namespace test3 { + class Bool; + template <class T> class User; + template <class T> T transform(class Bool, T); + + class Bool { + friend class User<bool>; + friend bool transform<>(Bool, bool); + + bool value; // expected-note 2 {{declared private here}} + }; + + template <class T> class User { + static T compute(Bool b) { + return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}} + } + }; + + template <class T> T transform(Bool b, T value) { + if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}} + return value; + return value + 1; + } + + template bool transform(Bool, bool); + template int transform(Bool, int); // expected-note {{requested here}} + + template class User<bool>; + template class User<int>; // expected-note {{requested here}} +} + +namespace test4 { + template <class T> class A { + template <class T0> friend class B; + bool foo(const A<T> *) const; + }; + + template <class T> class B { + bool bar(const A<T> *a, const A<T> *b) { + return a->foo(b); + } + }; + + template class B<int>; +} + +namespace test5 { + template <class T, class U=int> class A {}; + template <class T> class B { + template <class X, class Y> friend class A; + }; + template class B<int>; + template class A<int>; +} + +namespace Dependent { + template<typename T, typename Traits> class X; + template<typename T, typename Traits> + X<T, Traits> operator+(const X<T, Traits>&, const T*); + + template<typename T, typename Traits> class X { + typedef typename Traits::value_type value_type; + friend X operator+<>(const X&, const value_type*); + }; +} + +namespace test7 { + template <class T> class A { // expected-note {{previous definition is here}} + friend class B; + int x; // expected-note {{declared private here}} + }; + + class B { + int foo(A<int> &a) { + return a.x; + } + }; + + class C { + int foo(A<int> &a) { + return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}} + } + }; + + // This shouldn't crash. + template <class T> class D { + friend class A; // expected-error {{redefinition of 'A' as different kind of symbol}} + }; + template class D<int>; +} + +namespace test8 { + template <class N> class A { + static int x; + template <class T> friend void foo(); + }; + template class A<int>; + + template <class T> void foo() { + A<int>::x = 0; + } + template void foo<int>(); +} + +namespace test9 { + template <class T> class A { + class B; class C; + + int foo(B *b) { + return b->x; + } + + int foo(C *c) { + return c->x; // expected-error {{'x' is a private member}} + } + + class B { + int x; + friend int A::foo(B*); + }; + + class C { + int x; // expected-note {{declared private here}} + }; + }; + + template class A<int>; // expected-note {{in instantiation}} +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp new file mode 100644 index 0000000000000..c27261c96b68c --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template <int> int f(int); // expected-note 2{{candidate}} +template <signed char> int f(int); // expected-note 2{{candidate}} +int i1 = f<1>(0); // expected-error{{ambiguous}} +int i2 = f<1000>(0); // expected-error{{ambiguous}} + +namespace PR6707 { + template<typename T, T Value> + struct X { }; + + template<typename T, T Value> + void f(X<T, Value>); + + void g(X<int, 10> x) { + f(x); + } + + static const unsigned char ten = 10; + template<typename T, T Value, typename U> + void f2(X<T, Value>, X<U, Value>); + + void g2() { + f2(X<int, 10>(), X<char, ten>()); + } +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp new file mode 100644 index 0000000000000..2a7f16dc6b695 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<int i> class A { }; +template<short s> void f(A<s>); // expected-note{{failed template argument deduction}} + +void k1() { + A<1> a; + f(a); // expected-error{{no matching function for call}} + f<1>(a); +} +template<const short cs> class B { }; +template<short s> void g(B<s>); +void k2() { + B<1> b; + g(b); // OK: cv-qualifiers are ignored on template parameter types +} + +template<short s> void h(int (&)[s]); // expected-note{{failed template argument deduction}} +void k3() { + int array[5]; + h(array); + h<5>(array); +} + +template<short s> void h(int (&)[s], A<s>); // expected-note{{failed template argument deduction}} +void k4() { + A<5> a; + int array[5]; + h(array, a); // expected-error{{no matching function for call}} + h<5>(array, a); +} diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp index ed534a4627671..1ad4464c975c4 100644 --- a/test/CXX/temp/temp.res/temp.local/p1.cpp +++ b/test/CXX/temp/temp.res/temp.local/p1.cpp @@ -26,8 +26,7 @@ template <int N1, const int& N2, const int* N3> struct X1 { // FIXME: Test this clause. int i = 42; -int* iptr = &i; void test() { X0<int> x0; (void)x0; - X1<42, i, iptr> x1; (void)x1; + X1<42, i, &i> x1; (void)x1; } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp index f987c120a2de8..86cdcf80cbebf 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp @@ -6,7 +6,7 @@ template<typename T> struct A { }; struct X { - template<> friend void f<int>(int); // expected-error{{in class scope}} + template<> friend void f<int>(int); // expected-error{{in a friend}} template<> friend class A<int>; // expected-error{{cannot be a friend}} friend void f<float>(float); // okay |