aboutsummaryrefslogtreecommitdiff
path: root/test/CXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.def.odr/p1-var.cpp21
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp2
-rw-r--r--test/CXX/class.access/class.access.base/p1.cpp45
-rw-r--r--test/CXX/class.access/p4.cpp114
-rw-r--r--test/CXX/class.access/p6.cpp54
-rw-r--r--test/CXX/class/class.local/p2.cpp4
-rw-r--r--test/CXX/conv/conv.mem/p4.cpp65
-rw-r--r--test/CXX/conv/conv.qual/pr6089.cpp18
-rw-r--r--test/CXX/dcl.dcl/dcl.enum/p5.cpp56
-rw-r--r--test/CXX/dcl.dcl/dcl.link/p7.cpp30
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp9
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp6
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp12
-rw-r--r--test/CXX/dcl.decl/dcl.init/p6.cpp15
-rw-r--r--test/CXX/dcl.decl/dcl.name/p1.cpp16
-rw-r--r--test/CXX/expr/p8.cpp2
-rw-r--r--test/CXX/lex/lex.literal/lex.ccon/p1.cpp9
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp57
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp129
-rw-r--r--test/CXX/temp/temp.decls/temp.mem/p5.cpp2
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp2
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp3
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp95
-rw-r--r--test/CXX/temp/temp.names/p4.cpp15
-rw-r--r--test/CXX/temp/temp.res/temp.local/p1.cpp33
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp15
26 files changed, 794 insertions, 35 deletions
diff --git a/test/CXX/basic/basic.def.odr/p1-var.cpp b/test/CXX/basic/basic.def.odr/p1-var.cpp
new file mode 100644
index 000000000000..892f546ee545
--- /dev/null
+++ b/test/CXX/basic/basic.def.odr/p1-var.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++ [basic.def.odr]p1:
+// No translation unit shall contain more than one definition of any
+// variable, [...].
+
+// Bad: in C++, these are both definitions. None of that C99 tentative stuff.
+int i; // expected-note {{previous}}
+int i; // expected-error {{redefinition}}
+
+// OK: decl + def
+extern int j;
+int j;
+
+// OK: def + decl
+int k;
+extern int k;
+
+// Bad. The important thing here is that we don't emit the diagnostic twice.
+int l = 1; // expected-note {{previous}}
+int l = 2; // expected-error {{redefinition}}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp b/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp
index 76b6e2b57465..8126d28562ae 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp
@@ -15,4 +15,4 @@ namespace A {
}
class Ident<int> GlobalIdent;
-union Ident<int> GlobalIdent; // expected-error {{ tag type that does not match }}
+union Ident<int> GlobalIdent2; // expected-error {{ tag type that does not match }}
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp
index fd0d9f68e1e2..1bbcedb9a1e7 100644
--- a/test/CXX/class.access/class.access.base/p1.cpp
+++ b/test/CXX/class.access/class.access.base/p1.cpp
@@ -54,13 +54,13 @@ namespace test0 {
// of the base class are accessible as protected members of the
// derived class.
namespace test1 {
- class Base { // expected-note 6 {{constrained by protected inheritance}}
- public: int pub; static int spub; // expected-note 2 {{constrained by protected inheritance}}
+ class Base {
+ public: int pub; static int spub;
protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
private: int priv; static int spriv; // expected-note 8 {{declared private here}}
};
- class Test : protected Base {
+ class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}}
void test() {
pub++;
spub++;
@@ -79,19 +79,19 @@ namespace test1 {
};
void test(Test *t) {
- t->pub++; // expected-error {{protected member}}
+ t->pub++; // expected-error {{protected member}} expected-error {{protected base class}}
t->spub++; // expected-error {{protected member}}
- t->prot++; // expected-error {{protected member}}
+ t->prot++; // expected-error {{protected member}} expected-error {{protected base class}}
t->sprot++; // expected-error {{protected member}}
- t->priv++; // expected-error {{private member}}
+ t->priv++; // expected-error {{private member}} expected-error {{protected base class}}
t->spriv++; // expected-error {{private member}}
// Two possible errors here: one for Base, one for the member
- t->Base::pub++; // expected-error {{protected member}}
+ t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}}
t->Base::spub++; // expected-error {{protected member}}
- t->Base::prot++; // expected-error 2 {{protected member}}
+ t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}}
t->Base::sprot++; // expected-error 2 {{protected member}}
- t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}}
+ t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}}
t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}}
}
}
@@ -102,21 +102,20 @@ namespace test1 {
// the base class are accessible as private members of the derived
// class.
namespace test2 {
- class Base { //expected-note 6 {{constrained by private inheritance}}
+ class Base {
public:
- int pub; // expected-note {{constrained by private inheritance}}
- static int spub; // expected-note {{constrained by private inheritance}}
+ int pub;
+ static int spub;
protected:
- int prot; // expected-note {{constrained by private inheritance}} \
- // expected-note {{declared protected here}}
- static int sprot; // expected-note {{constrained by private inheritance}} \
- // expected-note {{declared protected here}}
+ int prot; // expected-note {{declared protected here}}
+ static int sprot; // expected-note {{declared protected here}}
private:
int priv; // expected-note 4 {{declared private here}}
static int spriv; // expected-note 4 {{declared private here}}
};
- class Test : private Base { // expected-note 6 {{'private' inheritance specifier here}}
+ class Test : private Base { // expected-note 6 {{declared private here}} \
+ // expected-note 10 {{constrained by private inheritance here}}
void test() {
pub++;
spub++;
@@ -135,18 +134,18 @@ namespace test2 {
};
void test(Test *t) {
- t->pub++; // expected-error {{private member}} expected-error {{inaccessible base class}}
+ t->pub++; // expected-error {{private member}} expected-error {{private base class}}
t->spub++; // expected-error {{private member}}
- t->prot++; // expected-error {{private member}} expected-error {{inaccessible base class}}
+ t->prot++; // expected-error {{private member}} expected-error {{private base class}}
t->sprot++; // expected-error {{private member}}
- t->priv++; // expected-error {{private member}} expected-error {{inaccessible base class}}
+ t->priv++; // expected-error {{private member}} expected-error {{private base class}}
t->spriv++; // expected-error {{private member}}
- t->Base::pub++; // expected-error {{private member}} expected-error {{inaccessible base class}}
+ t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}}
t->Base::spub++; // expected-error {{private member}}
- t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{inaccessible base class}}
+ t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}}
t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}}
- t->Base::priv++; // expected-error 2 {{private member}} expected-error {{inaccessible base class}}
+ t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}}
t->Base::spriv++; // expected-error 2 {{private member}}
}
}
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
new file mode 100644
index 000000000000..7aa614cd8b1a
--- /dev/null
+++ b/test/CXX/class.access/p4.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s
+
+// C++0x [class.access]p4:
+
+// Access control is applied uniformly to all names, whether the
+// names are referred to from declarations or expressions. In the
+// case of overloaded function names, access control is applied to
+// the function selected by overload resolution.
+
+class Public {} PublicInst;
+class Protected {} ProtectedInst;
+class Private {} PrivateInst;
+
+namespace test0 {
+ class A {
+ public:
+ void foo(Public&);
+ protected:
+ void foo(Protected&); // expected-note 2 {{declared protected here}}
+ private:
+ void foo(Private&); // expected-note 2 {{declared private here}}
+ };
+
+ void test(A *op) {
+ op->foo(PublicInst);
+ op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
+ op->foo(PrivateInst); // expected-error {{'foo' is a private member}}
+
+ void (A::*a)(Public&) = &A::foo;
+ void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}}
+ void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}}
+ }
+}
+
+// Member operators.
+namespace test1 {
+ class A {
+ public:
+ void operator+(Public&);
+ void operator[](Public&);
+ void operator()(Public&);
+ typedef void (*PublicSurrogate)(Public&);
+ operator PublicSurrogate() const;
+ protected:
+ void operator+(Protected&); // expected-note {{declared protected here}}
+ void operator[](Protected&); // expected-note {{declared protected here}}
+ void operator()(Protected&); // expected-note {{declared protected here}}
+ typedef void (*ProtectedSurrogate)(Protected&);
+ operator ProtectedSurrogate() const; // expected-note {{declared protected here}}
+ private:
+ void operator+(Private&); // expected-note {{declared private here}}
+ void operator[](Private&); // expected-note {{declared private here}}
+ void operator()(Private&); // expected-note {{declared private here}}
+ void operator-(); // expected-note {{declared private here}}
+ typedef void (*PrivateSurrogate)(Private&);
+ operator PrivateSurrogate() const; // expected-note {{declared private here}}
+ };
+ void operator+(const A &, Public&);
+ void operator+(const A &, Protected&);
+ void operator+(const A &, Private&);
+ void operator-(const A &);
+
+ void test(A &a, Public &pub, Protected &prot, Private &priv) {
+ a + pub;
+ a + prot; // expected-error {{'operator+' is a protected member}}
+ a + priv; // expected-error {{'operator+' is a private member}}
+ a[pub];
+ a[prot]; // expected-error {{'operator[]' is a protected member}}
+ a[priv]; // expected-error {{'operator[]' is a private member}}
+ a(pub);
+ a(prot); // expected-error {{'operator()' is a protected member}}
+ a(priv); // expected-error {{'operator()' is a private member}}
+ -a; // expected-error {{'operator-' is a private member}}
+
+ const A &ca = a;
+ ca + pub;
+ ca + prot;
+ ca + priv;
+ -ca;
+ // These are all surrogate calls
+ ca(pub);
+ ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}}
+ ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}}
+ }
+}
+
+// Implicit constructor calls.
+namespace test2 {
+ class A {
+ private:
+ A(); // expected-note {{declared private here}}
+
+ static A foo;
+ };
+
+ A a; // expected-error {{calling a private constructor}}
+ A A::foo; // okay
+}
+
+// Implicit destructor calls.
+namespace test3 {
+ class A{
+ private:
+ ~A(); // expected-note 3 {{declared private here}}
+ static A foo;
+ };
+
+ A a; // expected-error {{'~A' is a private member}}
+ A A::foo;
+
+ void foo(A param) { // expected-error {{'~A' is a private member}}
+ A local; // expected-error {{'~A' is a private member}}
+ }
+}
diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp
new file mode 100644
index 000000000000..aaf510a6d11f
--- /dev/null
+++ b/test/CXX/class.access/p6.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s
+
+// C++0x [class.access]p6:
+// All access controls in [class.access] affect the ability to
+// access a class member name from a particular scope. For purposes
+// of access control, the base-specifiers of a class and the
+// definitions of class members that appear outside of the class
+// definition are considered to be within the scope of that
+// class. In particular, access controls apply as usual to member
+// names accessed as part of a function return type, even though it
+// is not possible to determine the access privileges of that use
+// without first parsing the rest of the function
+// declarator. Similarly, access control for implicit calls to the
+// constructors, the conversion functions, or the destructor called
+// to create and destroy a static data member is performed as if
+// these calls appeared in the scope of the member's class.
+
+struct Public {}; struct Protected {}; struct Private {};
+
+namespace test0 {
+ class A {
+ typedef int type; // expected-note {{declared private here}}
+ type foo();
+ };
+
+ A::type foo() { } // expected-error {{'type' is a private member}}
+ A::type A::foo() { }
+}
+
+// conversion decls
+namespace test1 {
+ class A {
+ public:
+ A();
+ operator Public ();
+ A(Public);
+ protected:
+ operator Protected (); // expected-note {{declared protected here}}
+ A(Protected); // expected-note {{declared protected here}}
+ private:
+ operator Private (); // expected-note {{declared private here}}
+ A(Private); // expected-note {{declared private here}}
+ };
+
+ void test() {
+ A a;
+ Public pub = a;
+ Protected prot = a; // expected-error {{'operator Protected' is a protected member}}
+ Private priv = a; // expected-error {{'operator Private' is a private member}}
+ A apub = pub;
+ A aprot = prot; // expected-error {{protected constructor}}
+ A apriv = priv; // expected-error {{private constructor}}
+ }
+}
diff --git a/test/CXX/class/class.local/p2.cpp b/test/CXX/class/class.local/p2.cpp
index 56ff1e53a493..8d281a57e137 100644
--- a/test/CXX/class/class.local/p2.cpp
+++ b/test/CXX/class/class.local/p2.cpp
@@ -3,9 +3,9 @@
struct A { };
void f() {
- struct B : private A {}; // expected-note{{'private' inheritance specifier here}}
+ struct B : private A {}; // expected-note{{declared private here}}
B b;
- A *a = &b; // expected-error{{conversion from 'struct B' to inaccessible base class 'struct A'}}
+ A *a = &b; // expected-error{{cannot cast 'struct B' to its private base class 'struct A'}}
}
diff --git a/test/CXX/conv/conv.mem/p4.cpp b/test/CXX/conv/conv.mem/p4.cpp
new file mode 100644
index 000000000000..1ecbc47ffbb8
--- /dev/null
+++ b/test/CXX/conv/conv.mem/p4.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s
+
+struct Base {
+ int data;
+ int method();
+};
+int (Base::*data_ptr) = &Base::data;
+int (Base::*method_ptr)() = &Base::method;
+
+namespace test0 {
+ struct Derived : Base {};
+ void test() {
+ int (Derived::*d) = data_ptr;
+ int (Derived::*m)() = method_ptr;
+ }
+}
+
+// Can't be inaccessible.
+namespace test1 {
+ struct Derived : private Base {}; // expected-note 2 {{declared private here}}
+ void test() {
+ int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'struct Base' to 'struct test1::Derived'}}
+ int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'struct Base' to 'struct test1::Derived'}}
+ }
+};
+
+// Can't be ambiguous.
+namespace test2 {
+ struct A : Base {};
+ struct B : Base {};
+ struct Derived : A, B {};
+ void test() {
+ int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
+ int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
+ }
+}
+
+// Can't be virtual.
+namespace test3 {
+ struct Derived : virtual Base {};
+ void test() {
+ int (Derived::*d) = data_ptr; // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
+ int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
+ }
+}
+
+// Can't be virtual even if there's a non-virtual path.
+namespace test4 {
+ struct A : Base {};
+ struct Derived : Base, virtual A {};
+ void test() {
+ int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
+ int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
+ }
+}
+
+// PR6254: don't get thrown off by a virtual base.
+namespace test5 {
+ struct A {};
+ struct Derived : Base, virtual A {};
+ void test() {
+ int (Derived::*d) = data_ptr;
+ int (Derived::*m)() = method_ptr;
+ }
+}
diff --git a/test/CXX/conv/conv.qual/pr6089.cpp b/test/CXX/conv/conv.qual/pr6089.cpp
new file mode 100644
index 000000000000..ae75ec41bd8f
--- /dev/null
+++ b/test/CXX/conv/conv.qual/pr6089.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+bool is_char_ptr( const char* );
+
+template< class T >
+ long is_char_ptr( T /* r */ );
+
+// Note: the const here does not lead to a qualification conversion
+template< class T >
+ void make_range( T* const r, bool );
+
+template< class T >
+ void make_range( T& r, long );
+
+void first_finder( const char*& Search )
+{
+ make_range( Search, is_char_ptr(Search) );
+}
diff --git a/test/CXX/dcl.dcl/dcl.enum/p5.cpp b/test/CXX/dcl.dcl/dcl.enum/p5.cpp
new file mode 100644
index 000000000000..f26062416cbf
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.enum/p5.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s
+template<typename T> int force_same(T, T);
+
+// C++ [dcl.enum]p5:
+// [...] If the underlying type is not fixed, the type of each enumerator is
+// the type of its initializing value:
+// - If an initializer is specified for an enumerator, the initializing
+// value has the same type as the expression.
+enum Bullet1 {
+ Bullet1Val1 = 'a',
+ Bullet1Val2 = 10u,
+ Bullet1Val1IsChar = sizeof(force_same(Bullet1Val1, char(0))),
+ Bullet1Val2IsUnsigned = sizeof(force_same(Bullet1Val2, unsigned(0)))
+};
+
+// - If no initializer is specified for the first enumerator, the
+// initializing value has an unspecified integral type.
+enum Bullet2 {
+ Bullet2Val,
+ Bullet2ValIsInt = sizeof(force_same(Bullet2Val, int(0)))
+};
+
+// - Otherwise the type of the initializing value is the same as the type
+// of the initializing value of the preceding enumerator unless the
+// incremented value is not representable in that type, in which case the
+// type is an unspecified integral type sufficient to contain the
+// incremented value. If no such type exists, the program is ill-formed.
+enum Bullet3a {
+ Bullet3aVal1 = 17,
+ Bullet3aVal2,
+ Bullet3aVal2IsInt = sizeof(force_same(Bullet3aVal2, int(0))),
+ Bullet3aVal3 = 2147483647,
+ Bullet3aVal3IsInt = sizeof(force_same(Bullet3aVal3, int(0))),
+ Bullet3aVal4,
+ Bullet3aVal4IsUnsigned = sizeof(force_same(Bullet3aVal4, 0ul))
+};
+
+enum Bullet3b {
+ Bullet3bVal1 = 17u,
+ Bullet3bVal2,
+ Bullet3bVal2IsInt = sizeof(force_same(Bullet3bVal2, 0u)),
+ Bullet3bVal3 = 2147483647u,
+ Bullet3bVal3IsInt = sizeof(force_same(Bullet3bVal3, 0u)),
+ Bullet3bVal4,
+ Bullet3bVal4IsUnsigned = sizeof(force_same(Bullet3bVal4, 0ul))
+};
+
+enum Bullet3c {
+ Bullet3cVal1 = 0xFFFFFFFFFFFFFFFEull,
+ Bullet3cVal2,
+ Bullet3cVal3 // expected-warning{{not representable}}
+};
+
+// Following the closing brace of an enum-specifier, each enumerator has the
+// type of its enumeration.
+int array0[sizeof(force_same(Bullet3bVal3, Bullet3b(0)))? 1 : -1];
diff --git a/test/CXX/dcl.dcl/dcl.link/p7.cpp b/test/CXX/dcl.dcl/dcl.link/p7.cpp
new file mode 100644
index 000000000000..bd9ff3c3665c
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.link/p7.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct X { };
+
+// CHECK: @x1 = global %struct.X zeroinitializer
+// CHECK: @x4 = global %struct.X zeroinitializer
+// CHECK: @x2 = external global %struct.X
+// CHECK: @x3 = external global %struct.X
+extern "C" {
+
+
+ X x1;
+}
+
+extern "C" X x2;
+
+extern X x3;
+
+X x4;
+
+X& get(int i) {
+ if (i == 1)
+ return x1;
+ else if (i == 2)
+ return x2;
+ else if (i == 3)
+ return x3;
+ else
+ return x4;
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
index 16a09d836d16..fcc1334b1506 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -verify %s
-// XFAIL: *
class A {
public:
@@ -7,7 +6,11 @@ public:
explicit operator int(); // expected-warning {{explicit conversion functions are a C++0x extension}}
- explicit void f0(); // expected-error {{'explicit' cannot only be applied to constructor or conversion function}}
+ explicit void f0(); // expected-error {{'explicit' can only be applied to a constructor or conversion function}}
+
+ operator bool();
};
-explicit A::A() { } // expected-error {{'explicit' cannot be specified outside class definition}}
+explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}}
+explicit A::operator bool() { return false; } // expected-warning {{explicit conversion functions are a C++0x extension}}\
+ // expected-error {{'explicit' can only be specified inside the class definition}}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
index cf3db5175fa4..d9c5d014014a 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -68,17 +68,23 @@ void bind_lvalue_quals(volatile Base b, volatile Derived d,
volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Derived const volatile' drops qualifiers}}
volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}}
+
+ const volatile Base &bcvr1 = b;
+ const volatile Base &bcvr2 = d;
}
void bind_lvalue_to_rvalue() {
Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Base'}}
Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Derived'}}
+ const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a temporary of type 'struct Base'}}
+ const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a temporary of type 'struct Derived'}}
int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
}
void bind_lvalue_to_unrelated(Unrelated ur) {
Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a value of unrelated type 'struct Unrelated'}}
+ const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a value of unrelated type 'struct Unrelated'}}
}
void bind_lvalue_to_conv_lvalue() {
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
new file mode 100644
index 000000000000..cf529098dfe4
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5909 {
+ struct Foo {
+ int x : 20;
+ };
+
+ bool Test(const int& foo);
+
+ const Foo f = { 0 }; // It compiles without the 'const'.
+ bool z = Test(f.x);
+}
diff --git a/test/CXX/dcl.decl/dcl.init/p6.cpp b/test/CXX/dcl.decl/dcl.init/p6.cpp
new file mode 100644
index 000000000000..f627a199eca6
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/p6.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: Very incomplete!
+
+// If a program calls for the default initialization of an object of a
+// const-qualified type T, T shall be a class type with a
+// user-provided default constructor.
+struct NoUserDefault { };
+struct HasUserDefault { HasUserDefault(); };
+
+void test_const_default_init() {
+ const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'struct NoUserDefault const' requires a user-provided default constructor}}
+ const HasUserDefault x2;
+ const int x3; // expected-error{{default initialization of an object of const type 'int const'}}
+}
diff --git a/test/CXX/dcl.decl/dcl.name/p1.cpp b/test/CXX/dcl.decl/dcl.name/p1.cpp
new file mode 100644
index 000000000000..7586007cc7b3
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.name/p1.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace pr6200 {
+ struct v {};
+ struct s {
+ int i;
+ operator struct v() { return v(); };
+ };
+
+ void f()
+ {
+ // Neither of these is a declaration.
+ (void)new struct s;
+ (void)&s::operator struct v;
+ }
+}
diff --git a/test/CXX/expr/p8.cpp b/test/CXX/expr/p8.cpp
index cc834d9dc8d8..2f6c094301ee 100644
--- a/test/CXX/expr/p8.cpp
+++ b/test/CXX/expr/p8.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
int a0;
-const volatile int a1;
+const volatile int a1 = 2;
int a2[16];
int a3();
diff --git a/test/CXX/lex/lex.literal/lex.ccon/p1.cpp b/test/CXX/lex/lex.literal/lex.ccon/p1.cpp
new file mode 100644
index 000000000000..7b65f7ee8320
--- /dev/null
+++ b/test/CXX/lex/lex.literal/lex.ccon/p1.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Check types of char literals
+extern char a;
+extern __typeof('a') a;
+extern int b;
+extern __typeof('asdf') b;
+extern wchar_t c;
+extern __typeof(L'a') c;
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
new file mode 100644
index 000000000000..83365a2a082c
--- /dev/null
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.arg.nontype]p1:
+//
+// A template-argument for a non-type, non-template template-parameter shall
+// be one of:
+// -- an integral constant expression; or
+// -- the name of a non-type template-parameter ; or
+namespace non_type_tmpl_param {
+ template <int N> struct X0 { X0(); };
+ template <int N> X0<N>::X0() { }
+ template <int* N> struct X1 { X1(); };
+ template <int* N> X1<N>::X1() { }
+ template <int& N> struct X3 { X3(); };
+ template <int& N> X3<N>::X3() { }
+ template <int (*F)(int)> struct X4 { X4(); };
+ template <int (*F)(int)> X4<F>::X4() { }
+ template <typename T, int (T::* M)(int)> struct X5 { X5(); };
+ template <typename T, int (T::* M)(int)> X5<T, M>::X5() { }
+}
+
+// -- the address of an object or function with external linkage, including
+// function templates and function template-ids but excluding non-static
+// class members, expressed as & id-expression where the & is optional if
+// the name refers to a function or array, or if the corresponding
+// template-parameter is a reference; or
+namespace addr_of_obj_or_func {
+ template <int* p> struct X0 { };
+ template <int (*fp)(int)> struct X1 { };
+ // FIXME: Add reference template parameter tests.
+
+ int i = 42;
+ int iarr[10];
+ int f(int i);
+ template <typename T> T f_tmpl(T t);
+ void test() {
+ X0<&i> x0a;
+ X0<iarr> x0b;
+ X1<&f> x1a;
+ X1<f> x1b;
+ X1<f_tmpl> x1c;
+ X1<f_tmpl<int> > x1d;
+ }
+}
+
+// -- a constant expression that evaluates to a null pointer value (4.10); or
+// -- a constant expression that evaluates to a null member pointer value
+// (4.11); or
+// -- a pointer to member expressed as described in 5.3.1.
+
+namespace bad_args {
+ template <int* N> struct X0 { };
+ 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.
+}
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
new file mode 100644
index 000000000000..458aff2f0232
--- /dev/null
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.arg.nontype] p5:
+// The following conversions are performed on each expression used as
+// a non-type template-argument. If a non-type template-argument cannot be
+// converted to the type of the corresponding template-parameter then the
+// program is ill-formed.
+// -- for a non-type template-parameter of integral or enumeration type,
+// integral promotions (4.5) and integral conversions (4.7) are applied.
+// -- for a non-type template-parameter of type pointer to object,
+// qualification conversions (4.4) and the array-to-pointer conversion
+// (4.2) are applied; if the template-argument is of type
+// std::nullptr_t, the null pointer conversion (4.10) is applied.
+namespace pointer_to_object_parameters {
+ // PR6226
+ struct Str {
+ Str(const char *);
+ };
+
+ template<const char *s>
+ struct A {
+ Str get() { return s; }
+ };
+
+ char hello[6] = "Hello";
+ extern const char world[6];
+ const char world[6] = "world";
+ void test() {
+ (void)A<hello>().get();
+ (void)A<world>().get();
+ }
+
+ class X {
+ public:
+ X();
+ X(int, int);
+ operator int() const;
+ };
+
+ template<X const *Ptr> struct A2;
+
+ X *X_ptr;
+ X an_X;
+ X array_of_Xs[10];
+ A2<X_ptr> *a12;
+ 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}}
+
+ // PR6244
+ struct X1 {} X1v;
+ template <X1*> struct X2 { };
+ template <X1* Value> struct X3 : X2<Value> { };
+ struct X4 : X3<&X1v> { };
+}
+
+// -- For a non-type template-parameter of type reference to object, no
+// conversions apply. The type referred to by the reference may be more
+// cv-qualified than the (otherwise identical) type of the
+// template-argument. The template-parameter is bound directly to the
+// template-argument, which shall be an lvalue.
+namespace reference_parameters {
+ template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}}
+ template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}}
+ template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}}
+ template <const volatile int& N> struct S3 { };
+ int i;
+ extern const int ci;
+ volatile int vi;
+ extern const volatile int cvi;
+ void test() {
+ S0<i> s0;
+ S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}}
+ S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}}
+ S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}}
+
+ S1<i> s1;
+ S1<ci> s1c;
+ S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}}
+ S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}}
+
+ S2<i> s2;
+ S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}}
+ S2<vi> s2v;
+ S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}}
+
+ S3<i> s3;
+ S3<ci> s3c;
+ S3<vi> s3v;
+ S3<cvi> s3cv;
+ }
+
+ namespace PR6250 {
+ template <typename T, const T &ref> void inc() {
+ ref++; // expected-error{{read-only variable is not assignable}}
+ }
+
+ template<typename T, const T &ref> void bind() {
+ T &ref2 = ref; // expected-error{{drops qualifiers}}
+ }
+
+ int counter;
+ void test() {
+ inc<int, counter>(); // expected-note{{instantiation of}}
+ bind<int, counter>(); // expected-note{{instantiation of}}
+ }
+ }
+}
+
+// -- For a non-type template-parameter of type pointer to function, the
+// function-to-pointer conversion (4.3) is applied; if the
+// template-argument is of type std::nullptr_t, the null pointer
+// conversion (4.10) is applied. If the template-argument represents
+// a set of overloaded functions (or a pointer to such), the matching
+// function is selected from the set (13.4).
+// -- 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).
+// -- 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).
+// -- 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.
diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
index 098ffa4dec75..b0078d4bdb6d 100644
--- a/test/CXX/temp/temp.decls/temp.mem/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -55,7 +55,7 @@ template double Foo::As2();
// Partial ordering with conversion function templates.
struct X0 {
template<typename T> operator T*() {
- T x;
+ T x = 1;
x = 17; // expected-error{{read-only variable is not assignable}}
}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
index 8fb736ca0313..95f9640a0b43 100644
--- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate function}}
+template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}}
void g() {
f<int,char*,double>("aa",3.0);
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
index bcfb71c987eb..1b7310f00055 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
@@ -15,7 +15,8 @@ void test_f1(int *ip, float fv) {
f1(ip, fv);
}
-template<typename T> void f2(T*, T*); // expected-note 2 {{candidate function}}
+// TODO: this diagnostic can and should improve
+template<typename T> void f2(T*, T*); // expected-note 2 {{candidate template ignored: failed template argument deduction}}
struct ConvToIntPtr {
operator int*() const;
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
new file mode 100644
index 000000000000..6edf079b3524
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+ template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{failed template argument deduction}}\
+ // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}}
+
+ template<class A> void temp(A);
+ void test0() {
+ // okay: deduce T=int from first argument, A=int during overload
+ apply(0, &temp);
+ apply(0, &temp<>);
+
+ // okay: deduce T=int from first and second arguments
+ apply(0, &temp<int>);
+
+ // deduction failure: T=int from first, T=long from second
+ apply(0, &temp<long>); // expected-error {{no matching function for call to 'apply'}}
+ }
+
+ void over(int);
+ int over(long);
+
+ void test1() {
+ // okay: deductions match
+ apply(0, &over);
+
+ // deduction failure: deduced T=long from first argument, T=int from second
+ apply(0L, &over); // expected-error {{no matching function for call to 'apply'}}
+ }
+
+ void over(short);
+
+ void test2() {
+ // deduce T=int from first arg, second arg is undeduced context,
+ // pick correct overload of 'over' during overload resolution for 'apply'
+ apply(0, &over);
+ }
+
+ template<class A, class B> B temp2(A);
+ void test3() {
+ // deduce T=int from first arg, A=int B=void during overload resolution
+ apply(0, &temp2);
+ apply(0, &temp2<>);
+ apply(0, &temp2<int>);
+
+ // overload failure
+ apply(0, &temp2<long>); // expected-error {{no matching function for call to 'apply'}}
+ }
+}
+
+namespace test1 {
+ template<class T> void invoke(void (*f)(T)) { f(T()); } // expected-note 6 {{couldn't infer template argument}} \
+ // expected-note {{failed template argument deduction}}
+
+ template<class T> void temp(T);
+ void test0() {
+ // deduction failure: overload has template => undeduced context
+ invoke(&temp); // expected-error {{no matching function for call to 'invoke'}}
+ invoke(&temp<>); // expected-error {{no matching function for call to 'invoke'}}
+
+ // okay: full template-id
+ invoke(&temp<int>);
+ }
+
+ void over(int);
+ int over(long);
+
+ void test1() {
+ // okay: only one overload matches
+ invoke(&over);
+ }
+
+ void over(short);
+
+ void test2() {
+ // deduction failure: overload has multiple matches => undeduced context
+ invoke(&over); // expected-error {{no matching function for call to 'invoke'}}
+ }
+
+ template<class A, class B> B temp2(A);
+ void test3() {
+ // deduction failure: overload has template => undeduced context
+ // (even though partial application temp2<int> could in theory
+ // let us infer T=int)
+ invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}}
+ invoke(&temp2<>); // expected-error {{no matching function for call to 'invoke'}}
+ invoke(&temp2<int>); // expected-error {{no matching function for call to 'invoke'}}
+
+ // okay: full template-id
+ invoke(&temp2<int, void>);
+
+ // overload failure
+ invoke(&temp2<int, int>); // expected-error {{no matching function for call to 'invoke'}}
+ }
+}
diff --git a/test/CXX/temp/temp.names/p4.cpp b/test/CXX/temp/temp.names/p4.cpp
new file mode 100644
index 000000000000..103a1bd537f8
--- /dev/null
+++ b/test/CXX/temp/temp.names/p4.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct meta {
+ template<typename U>
+ struct apply {
+ typedef U* type;
+ };
+};
+
+template<typename T, typename U>
+void f(typename T::template apply<U>::type);
+
+void test_f(int *ip) {
+ f<meta, int>(ip);
+}
diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp
new file mode 100644
index 000000000000..ed534a462767
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.local]p1:
+// Like normal (non-template) classes, class templates have an
+// injected-class-name (Clause 9). The injected-class-name can be used with
+// or without a template-argument-list. When it is used without
+// a template-argument-list, it is equivalent to the injected-class-name
+// followed by the template-parameters of the class template enclosed in <>.
+
+template <typename T> struct X0 {
+ X0();
+ ~X0();
+ X0 f(const X0&);
+};
+
+// Test non-type template parameters.
+template <int N1, const int& N2, const int* N3> struct X1 {
+ X1();
+ ~X1();
+ X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; }
+};
+
+// When it is used with a template-argument-list, it refers to the specified
+// class template specialization, which could be the current specialization
+// or another specialization.
+// FIXME: Test this clause.
+
+int i = 42;
+int* iptr = &i;
+void test() {
+ X0<int> x0; (void)x0;
+ X1<42, i, iptr> x1; (void)x1;
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
index 3b5b5afa8ed9..88cfc5d7c397 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
@@ -18,7 +18,18 @@ namespace test1 {
};
typedef A<int> AA;
- template <> int AA::foo = 0; // expected-error {{cannot use typedef}}
- int AA::bar = 1; // expected-error {{cannot use typedef}} expected-error {{template specialization requires 'template<>'}}
+ template <> int AA::foo = 0;
+ int AA::bar = 1; // expected-error {{template specialization requires 'template<>'}}
int A<float>::bar = 2; // expected-error {{template specialization requires 'template<>'}}
+
+ template <> class A<double> {
+ public:
+ static int foo; // expected-note{{attempt to specialize}}
+ static int bar;
+ };
+
+ typedef A<double> AB;
+ template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} \
+ // expected-error{{does not specialize}}
+ int AB::bar = 1;
}