summaryrefslogtreecommitdiff
path: root/test/CXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp12
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp13
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp9
-rw-r--r--test/CXX/class.access/class.access.base/p5.cpp75
-rw-r--r--test/CXX/class.access/class.friend/p1.cpp43
-rw-r--r--test/CXX/class.access/p4.cpp69
-rw-r--r--test/CXX/class.derived/class.abstract/p4.cpp80
-rw-r--r--test/CXX/class.derived/class.abstract/p5.cpp23
-rw-r--r--test/CXX/class.derived/class.virtual/p2.cpp37
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp43
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp14
-rw-r--r--test/CXX/stmt.stmt/stmt.select/p3.cpp11
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp4
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp80
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p1.cpp131
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp26
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp31
-rw-r--r--test/CXX/temp/temp.res/temp.local/p1.cpp3
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp2
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