aboutsummaryrefslogtreecommitdiff
path: root/test/CXX
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
commitbab175ec4b075c8076ba14c762900392533f6ee4 (patch)
tree01f4f29419a2cb10abe13c1e63cd2a66068b0137 /test/CXX
parent8b7a8012d223fac5d17d16a66bb39168a9a1dfc0 (diff)
Notes
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp4
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp19
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp2
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp19
-rw-r--r--test/CXX/class.access/class.friend/p1.cpp21
-rw-r--r--test/CXX/class.access/p4.cpp82
-rw-r--r--test/CXX/class.derived/class.abstract/p16.cpp18
-rw-r--r--test/CXX/class.derived/class.abstract/p2.cpp23
-rw-r--r--test/CXX/class.derived/class.abstract/p3.cpp97
-rw-r--r--test/CXX/class/class.union/p1.cpp2
-rw-r--r--test/CXX/conv/conv.fctptr/p1.cpp43
-rw-r--r--test/CXX/cpp/cpp.predefined/p1.cpp9
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp9
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp157
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp6
-rw-r--r--test/CXX/dcl.decl/dcl.decomp/p2.cpp34
-rw-r--r--test/CXX/dcl.decl/dcl.decomp/p3.cpp232
-rw-r--r--test/CXX/dcl.decl/dcl.decomp/p4.cpp200
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp36
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp2
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4.cpp13
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp8
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp23
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.init/p5.cpp41
-rw-r--r--test/CXX/dcl.decl/dcl.init/p7.cpp2
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp14
-rw-r--r--test/CXX/drs/dr0xx.cpp130
-rw-r--r--test/CXX/drs/dr10xx.cpp14
-rw-r--r--test/CXX/drs/dr118.cpp26
-rw-r--r--test/CXX/drs/dr12xx.cpp37
-rw-r--r--test/CXX/drs/dr13xx.cpp130
-rw-r--r--test/CXX/drs/dr14xx.cpp28
-rw-r--r--test/CXX/drs/dr158.cpp27
-rw-r--r--test/CXX/drs/dr15xx.cpp218
-rw-r--r--test/CXX/drs/dr16xx.cpp49
-rw-r--r--test/CXX/drs/dr18xx.cpp11
-rw-r--r--test/CXX/drs/dr1xx.cpp41
-rw-r--r--test/CXX/drs/dr2xx.cpp49
-rw-r--r--test/CXX/drs/dr4xx.cpp36
-rw-r--r--test/CXX/drs/dr5xx.cpp20
-rw-r--r--test/CXX/drs/dr6xx.cpp83
-rw-r--r--test/CXX/except/except.spec/p2-places-1z.cpp17
-rw-r--r--test/CXX/except/except.spec/p2-places.cpp2
-rw-r--r--test/CXX/except/except.spec/p5-pointers.cpp12
-rw-r--r--test/CXX/expr/expr.cond/p4.cpp10
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp24
-rw-r--r--test/CXX/expr/expr.const/p3-0x.cpp15
-rw-r--r--test/CXX/expr/expr.post/expr.static.cast/p3-p4-0x.cpp43
-rw-r--r--test/CXX/expr/expr.post/expr.static.cast/p7.cpp10
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp4
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp10
-rw-r--r--test/CXX/expr/expr.unary/expr.delete/p10.cpp25
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p14.cpp69
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p20-0x.cpp57
-rw-r--r--test/CXX/expr/p13.cpp51
-rw-r--r--test/CXX/over/over.built/p15.cpp83
-rw-r--r--test/CXX/over/over.built/p16.cpp75
-rw-r--r--test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.scs/p3.cpp12
-rw-r--r--test/CXX/over/over.oper/over.literal/p6.cpp4
-rw-r--r--test/CXX/over/over.over/p1.cpp23
-rw-r--r--test/CXX/special/class.copy/implicit-move-def.cpp2
-rw-r--r--test/CXX/special/class.copy/p20.cpp3
-rw-r--r--test/CXX/special/class.dtor/p3-0x.cpp2
-rw-r--r--test/CXX/special/class.dtor/p5-0x.cpp2
-rw-r--r--test/CXX/special/class.dtor/p9.cpp37
-rw-r--r--test/CXX/special/class.init/class.inhctor.init/p1.cpp7
-rw-r--r--test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp5
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp106
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp9
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp17
-rw-r--r--test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp2
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p1.cpp2
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp4
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp5
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp37
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp48
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p5.cpp61
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp2
-rw-r--r--test/CXX/temp/temp.spec/no-body.cpp2
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp28
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp18
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p4.cpp15
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp2
84 files changed, 2703 insertions, 278 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
index 004d1e491f176..ca17ba50ac299 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
@@ -9,7 +9,7 @@ namespace test0 {
typedef int A; // expected-note {{declared here}}
int test() {
- struct A a; // expected-error {{elaborated type refers to a typedef}}
+ struct A a; // expected-error {{typedef 'A' cannot be referenced with a struct specifier}}
return a.foo;
}
}
@@ -18,7 +18,7 @@ namespace test0 {
template <class> class A; // expected-note {{declared here}}
int test() {
- struct A a; // expected-error {{elaborated type refers to a template}}
+ struct A a; // expected-error {{template 'A' cannot be referenced with a struct specifier}}
return a.foo;
}
}
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp
new file mode 100644
index 0000000000000..9e3210c6650f7
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++1z -fsized-deallocation -fexceptions -verify %s
+
+using size_t = decltype(sizeof(0));
+
+namespace std { enum class align_val_t : size_t {}; }
+
+// p2 says "A template instance is never a usual deallocation function,
+// regardless of its signature." We (and every other implementation) assume
+// this means "A function template specialization [...]"
+template<typename...Ts> struct A {
+ void *operator new(size_t);
+ void operator delete(void*, Ts...) = delete; // expected-note 4{{deleted}}
+};
+
+auto *a1 = new A<>; // expected-error {{deleted}}
+auto *a2 = new A<size_t>; // expected-error {{deleted}}
+auto *a3 = new A<std::align_val_t>; // expected-error {{deleted}}
+auto *a4 = new A<size_t, std::align_val_t>; // expected-error {{deleted}}
+auto *a5 = new A<std::align_val_t, size_t>; // ok, not usual
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
index 9819ea0293f64..41aeeee73edaf 100644
--- a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp
@@ -1,3 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify %s
// expected-no-diagnostics
namespace std {
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 47b51585556f8..257aca1c3f7bf 100644
--- a/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp
@@ -1,3 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -fexceptions -fcxx-exceptions -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -fexceptions -fcxx-exceptions -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
int *use_new(int N) {
if (N == 1)
@@ -19,10 +21,21 @@ namespace std {
typedef __SIZE_TYPE__ size_t;
}
-void* operator new(std::size_t) throw(std::bad_alloc); // expected-note{{previous declaration}}
+void* operator new(std::size_t) throw(std::bad_alloc);
+#if __cplusplus < 201103L
+// expected-note@-2 {{previous declaration}}
+#endif
void* operator new[](std::size_t) throw(std::bad_alloc);
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()'}}
+void* operator new(std::size_t);
+#if __cplusplus < 201103L
+// expected-warning@-2 {{'operator new' is missing exception specification 'throw(std::bad_alloc)'}}
+#endif
+void operator delete(void*);
+#if __cplusplus < 201103L
+// expected-warning@-2 {{'operator delete' is missing exception specification 'throw()'}}
+#else
+// expected-warning@-4 {{previously declared with an explicit exception specification redeclared with an implicit}}
+#endif
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index 54069b6b87bee..b6a1bcdab926f 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -1,3 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
// RUN: %clang_cc1 -fsyntax-only -verify %s
// C++'0x [class.friend] p1:
@@ -216,9 +219,17 @@ namespace test6 {
struct A {};
struct B {
- friend A::A();
+ friend
+#if __cplusplus >= 201103L
+ constexpr
+#endif
+ A::A();
friend A::~A();
- friend A &A::operator=(const A&);
+ friend
+#if __cplusplus >= 201402L
+ constexpr
+#endif
+ A &A::operator=(const A&);
};
}
@@ -233,7 +244,11 @@ namespace test7 {
class A {
friend void X<int>::foo();
friend X<int>::X();
- friend X<int>::X(const X&);
+ friend
+#if __cplusplus >= 201103L
+ constexpr
+#endif
+ X<int>::X(const X&);
private:
A(); // expected-note 2 {{declared private here}}
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 435b09920df63..f010ad5a2cb3b 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -1,3 +1,5 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
// C++0x [class.access]p4:
@@ -88,7 +90,7 @@ namespace test1 {
namespace test2 {
class A {
private:
- A(); // expected-note 3 {{declared private here}}
+ A(); // expected-note 1+{{declared private here}}
static A foo;
};
@@ -96,6 +98,7 @@ namespace test2 {
A a; // expected-error {{calling a private constructor}}
A A::foo; // okay
+#if __cplusplus < 201103L
class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}}
B b; // expected-note{{implicit default constructor}}
@@ -106,6 +109,19 @@ namespace test2 {
class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private default constructor}}
D d; // expected-note{{implicit default constructor}}
+#else
+ class B : A { }; // expected-note {{base class 'test2::A' has an inaccessible default constructor}}
+ B b; // expected-error {{call to implicitly-deleted default constructor}}
+
+ // FIXME: Do a better job of explaining how we get here from class D.
+ class C : virtual A { // expected-note {{default constructor of 'D' is implicitly deleted because base class 'test2::A' has an inaccessible default constructor}}
+ public:
+ C();
+ };
+
+ class D : C { };
+ D d; // expected-error {{call to implicitly-deleted default constructor}}
+#endif
}
// Implicit destructor calls.
@@ -123,6 +139,7 @@ namespace test3 {
A local; // expected-error {{variable of type 'test3::A' has private destructor}}
}
+#if __cplusplus < 201103L
template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
// expected-error {{base class 'Base<2>' has private destructor}}
@@ -152,6 +169,33 @@ namespace test3 {
{};
Derived3 d3; // expected-note {{implicit default constructor}}\
// expected-note{{implicit destructor}}}
+#else
+ template <unsigned N> class Base { ~Base(); }; // expected-note 4{{declared private here}}
+ class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 1{{declared private here}}
+ class Base3 : virtual Base<3> { public: ~Base3(); };
+
+ // These don't cause diagnostics because we don't need the destructor.
+ class Derived0 : Base<0> { ~Derived0(); };
+ class Derived1 : Base<1> { };
+
+ class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
+ // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
+ Base<0>, // expected-error {{base class 'Base<0>' has private destructor}}
+ virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
+ Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
+ virtual Base3
+ {
+ ~Derived2() {}
+ };
+
+ class Derived3 :
+ Base<0>, // expected-note {{deleted because base class 'Base<0>' has an inaccessible destructor}}
+ virtual Base<1>,
+ Base2,
+ virtual Base3
+ {};
+ Derived3 d3; // expected-error {{implicitly-deleted default constructor}}
+#endif
}
// Conversion functions.
@@ -201,9 +245,13 @@ namespace test4 {
// Implicit copy assignment operator uses.
namespace test5 {
class A {
- void operator=(const A &); // expected-note 2 {{implicitly declared private here}}
+ void operator=(const A &);
+#if __cplusplus < 201103L
+ // expected-note@-2 2{{implicitly declared private here}}
+#endif
};
+#if __cplusplus < 201103L
class Test1 { A a; }; // expected-error {{private member}}
void test1() {
Test1 a;
@@ -215,15 +263,32 @@ namespace test5 {
Test2 a;
a = Test2(); // expected-note{{implicit copy}}
}
+#else
+ class Test1 { A a; }; // expected-note {{because field 'a' has an inaccessible copy assignment operator}}
+ void test1() {
+ Test1 a;
+ a = Test1(); // expected-error {{copy assignment operator is implicitly deleted}}
+ }
+
+ class Test2 : A {}; // expected-note {{because base class 'test5::A' has an inaccessible copy assignment operator}}
+ void test2() {
+ Test2 a;
+ a = Test2(); // expected-error {{copy assignment operator is implicitly deleted}}
+ }
+#endif
}
// Implicit copy constructor uses.
namespace test6 {
class A {
public: A();
- private: A(const A &); // expected-note 2 {{declared private here}}
+ private: A(const A &);
+#if __cplusplus < 201103L
+ // expected-note@-2 2{{declared private here}}
+#endif
};
+#if __cplusplus < 201103L
class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
void test1(const Test1 &t) {
Test1 a = t; // expected-note{{implicit copy}}
@@ -233,6 +298,17 @@ namespace test6 {
void test2(const Test2 &t) {
Test2 a = t; // expected-note{{implicit copy}}
}
+#else
+ class Test1 { A a; }; // expected-note {{field 'a' has an inaccessible copy constructor}}
+ void test1(const Test1 &t) {
+ Test1 a = t; // expected-error{{implicitly-deleted}}
+ }
+
+ class Test2 : A {}; // expected-note {{base class 'test6::A' has an inaccessible copy constructor}}
+ void test2(const Test2 &t) {
+ Test2 a = t; // expected-error{{implicitly-deleted}}
+ }
+#endif
}
// Redeclaration lookups are not accesses.
diff --git a/test/CXX/class.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp
index 2053218ca5b5f..29adbccac4795 100644
--- a/test/CXX/class.derived/class.abstract/p16.cpp
+++ b/test/CXX/class.derived/class.abstract/p16.cpp
@@ -31,12 +31,20 @@ private:
D &operator=(D&&) = default;
virtual ~D(); // expected-note 2{{here}}
};
-struct E : D {}; // expected-error {{deleted function '~E' cannot override a non-deleted function}} \
- // expected-error {{deleted function 'operator=' cannot override a non-deleted function}}
+struct E : D {};
+// expected-error@-1 {{deleted function '~E' cannot override a non-deleted function}}
+// expected-note@-2 {{destructor of 'E' is implicitly deleted because base class 'D' has an inaccessible destructor}}
+// expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}}
+// expected-note@-4 {{copy assignment operator of 'E' is implicitly deleted because base class 'D' has an inaccessible copy assignment operator}}
struct F : D {};
-struct G : D {}; // expected-error {{deleted function '~G' cannot override a non-deleted function}}
- // expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}}
+struct G : D {};
+// expected-error@-1 {{deleted function '~G' cannot override a non-deleted function}}
+// expected-note@-2 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
+// expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}}
+// expected-note@-4 {{destructor of 'G' is implicitly deleted because base class 'D' has an inaccessible destructor}}
struct H : D {
- H &operator=(H&&) = default; // expected-error {{deleted function 'operator=' cannot override a non-deleted function}}
+ H &operator=(H&&) = default;
+ // expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}}
+ // expected-note@-3 {{move assignment operator of 'H' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
~H();
};
diff --git a/test/CXX/class.derived/class.abstract/p2.cpp b/test/CXX/class.derived/class.abstract/p2.cpp
new file mode 100644
index 0000000000000..713a5269f1431
--- /dev/null
+++ b/test/CXX/class.derived/class.abstract/p2.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+// no objects of an abstract class can be created except as subobjects of a
+// class derived from it
+
+struct A {
+ A() {}
+ A(int) : A() {} // ok
+
+ virtual void f() = 0; // expected-note 1+{{unimplemented}}
+};
+
+void f(A &&a);
+
+void g() {
+ f({}); // expected-error {{abstract class}}
+ f({0}); // expected-error {{abstract class}}
+ f(0); // expected-error {{abstract class}}
+}
+
+struct B : A {
+ B() : A() {} // ok
+};
diff --git a/test/CXX/class.derived/class.abstract/p3.cpp b/test/CXX/class.derived/class.abstract/p3.cpp
new file mode 100644
index 0000000000000..ad5b874788359
--- /dev/null
+++ b/test/CXX/class.derived/class.abstract/p3.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+struct A {
+ A() {}
+ A(int) : A() {} // ok
+
+ virtual void f() = 0; // expected-note 1+{{unimplemented}}
+};
+
+template<typename> struct SecretlyAbstract {
+ SecretlyAbstract();
+ SecretlyAbstract(int);
+ virtual void f() = 0; // expected-note 1+{{unimplemented}}
+};
+using B = SecretlyAbstract<int>;
+using C = SecretlyAbstract<float>;
+using D = SecretlyAbstract<char>[1];
+
+B b; // expected-error {{abstract class}}
+D d; // expected-error {{abstract class}}
+
+template<int> struct N;
+
+// Note: C is not instantiated anywhere in this file, so we never discover that
+// it is in fact abstract. The C++ standard suggests that we need to
+// instantiate in all cases where abstractness could affect the validity of a
+// program, but that breaks a *lot* of code, so we don't do that.
+//
+// FIXME: Once DR1640 is resolved, remove the check on forming an abstract
+// array type entirely. The only restriction we need is that you can't create
+// an object of abstract (most-derived) type.
+
+
+// An abstract class shall not be used
+
+// - as a parameter type
+void f(A&);
+void f(A); // expected-error {{abstract class}}
+void f(A[1]); // expected-error {{abstract class}}
+void f(B); // expected-error {{abstract class}}
+void f(B[1]); // expected-error {{abstract class}}
+void f(C);
+void f(C[1]);
+void f(D); // expected-error {{abstract class}}
+void f(D[1]); // expected-error {{abstract class}}
+
+// - as a function return type
+A &f(N<0>);
+A *f(N<1>);
+A f(N<2>); // expected-error {{abstract class}}
+A (&f(N<3>))[2]; // expected-error {{abstract class}}
+B f(N<4>); // expected-error {{abstract class}}
+B (&f(N<5>))[2]; // expected-error {{abstract class}}
+C f(N<6>);
+C (&f(N<7>))[2];
+
+// - as the type of an explicit conversion
+void g(A&&);
+void h() {
+ A(); // expected-error {{abstract class}}
+ A(0); // expected-error {{abstract class}}
+ A{}; // expected-error {{abstract class}}
+ A{0}; // expected-error {{abstract class}}
+ (A)(0); // expected-error {{abstract class}}
+ (A){}; // expected-error {{abstract class}}
+ (A){0}; // expected-error {{abstract class}}
+
+ D(); // expected-error {{array type}}
+ D{}; // expected-error {{abstract class}}
+ D{0}; // expected-error {{abstract class}}
+ (D){}; // expected-error {{abstract class}}
+ (D){0}; // expected-error {{abstract class}}
+}
+
+template<typename T> void t(T); // expected-note 2{{abstract class}}
+void i(A &a, B &b, C &c, D &d) {
+ // FIXME: These should be handled consistently. We currently reject the first
+ // two early because we (probably incorrectly, depending on dr1640) take
+ // abstractness into account in forming implicit conversion sequences.
+ t(a); // expected-error {{no matching function}}
+ t(b); // expected-error {{no matching function}}
+ t(c); // expected-error {{allocating an object of abstract class type}}
+ t(d); // ok, decays to pointer
+}
+
+struct E : A {
+ E() : A() {} // ok
+ E(int n) : A( A(n) ) {} // expected-error {{abstract class}}
+};
+
+namespace std {
+ template<typename T> struct initializer_list {
+ const T *begin, *end;
+ initializer_list();
+ };
+}
+std::initializer_list<A> ila = {1, 2, 3, 4}; // expected-error {{abstract class}}
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
index 439cc9cec8dad..84ce1c991533d 100644
--- a/test/CXX/class/class.union/p1.cpp
+++ b/test/CXX/class/class.union/p1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
void abort() __attribute__((noreturn));
diff --git a/test/CXX/conv/conv.fctptr/p1.cpp b/test/CXX/conv/conv.fctptr/p1.cpp
new file mode 100644
index 0000000000000..be9c050af51ef
--- /dev/null
+++ b/test/CXX/conv/conv.fctptr/p1.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s -triple x86_64-unknown-unknown
+
+struct S;
+
+typedef void Nothrow() noexcept;
+typedef void Throw();
+
+Nothrow *a;
+Throw *b;
+Nothrow S::*c;
+Throw S::*d;
+
+void test() {
+ a = b; // expected-error {{assigning to 'Nothrow *' (aka 'void (*)() noexcept') from incompatible type 'Throw *' (aka 'void (*)()'): different exception specifications}}
+ b = a;
+ c = d; // expected-error {{assigning to 'Nothrow S::*' from incompatible type 'Throw S::*': different exception specifications}}
+ d = c;
+
+ // Function pointer conversions do not combine properly with qualification conversions.
+ // FIXME: This seems like a defect.
+ Nothrow *const *pa = b; // expected-error {{cannot initialize}}
+ Throw *const *pb = a; // expected-error {{cannot initialize}}
+ Nothrow *const S::*pc = d; // expected-error {{cannot initialize}}
+ Throw *const S::*pd = c; // expected-error {{cannot initialize}}
+}
+
+// ... The result is a pointer to the function.
+void f() noexcept;
+constexpr void (*p)() = &f;
+static_assert(f == p);
+
+struct S { void f() noexcept; };
+constexpr void (S::*q)() = &S::f;
+static_assert(q == &S::f);
+
+
+namespace std_example {
+ void (*p)();
+ void (**pp)() noexcept = &p; // expected-error {{cannot initialize a variable of type 'void (**)() noexcept' with an rvalue of type 'void (**)()'}}
+
+ struct S { typedef void (*p)(); operator p(); }; // expected-note {{candidate}}
+ void (*q)() noexcept = S(); // expected-error {{no viable conversion from 'std_example::S' to 'void (*)() noexcept'}}
+}
diff --git a/test/CXX/cpp/cpp.predefined/p1.cpp b/test/CXX/cpp/cpp.predefined/p1.cpp
new file mode 100644
index 0000000000000..c0dcbd54f3873
--- /dev/null
+++ b/test/CXX/cpp/cpp.predefined/p1.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify -triple x86_64-linux-gnu -DALIGN=16
+// RUN: %clang_cc1 -std=c++1z %s -verify -fnew-alignment=2 -DALIGN=2
+// RUN: %clang_cc1 -std=c++1z %s -verify -fnew-alignment=256 -DALIGN=256
+
+// expected-no-diagnostics
+
+#if ALIGN != __STDCPP_DEFAULT_NEW_ALIGNMENT__
+#error wrong value for __STDCPP_DEFAULT_NEW_ALIGNMENT__
+#endif
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
index f92362380a1c2..39bed7db7ab38 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -1,13 +1,18 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// FIXME: We should probably suppress the warning on reopening an inline
+// namespace without the inline keyword if it's not the first opening of the
+// namespace in the file, because there's no risk of the inlineness differing
+// across TUs in that case.
+
namespace NIL {} // expected-note {{previous definition}}
inline namespace NIL {} // expected-error {{cannot be reopened as inline}}
inline namespace IL {} // expected-note {{previous definition}}
-namespace IL {} // expected-warning{{inline namespace cannot be reopened as a non-inline namespace}}
+namespace IL {} // expected-warning{{inline namespace reopened as a non-inline namespace}}
namespace {} // expected-note {{previous definition}}
inline namespace {} // expected-error {{cannot be reopened as inline}}
namespace X {
inline namespace {} // expected-note {{previous definition}}
- namespace {} // expected-warning {{cannot be reopened as a non-inline namespace}}
+ namespace {} // expected-warning {{inline namespace reopened as a non-inline namespace}}
}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
index 6c63f061ab0f1..0ea4eeb1e9b08 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
// RUN: not %clang_cc1 -fsyntax-only -std=c++98 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX98 %s
// RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX11 %s
// C++0x N2914.
@@ -44,10 +45,158 @@ void f() {
#endif
}
-template <typename T>
-struct PR21933 : T {
- static void StaticFun() { using T::member; } // expected-error{{using declaration cannot refer to class member}}
-};
+namespace PR21933 {
+ struct A { int member; };
+ struct B { static int member; };
+ enum C { member };
+
+ template <typename T>
+ struct X {
+ static void StaticFun() {
+ using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
+#if __cplusplus < 201103L
+ // expected-error@-2 {{cannot be used prior to '::'}}
+#endif
+ (void)member;
+ }
+ };
+ template<typename T>
+ struct Y : T {
+ static void StaticFun() {
+ using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
+ (void)member;
+ }
+ };
+
+ void f() {
+ X<A>::StaticFun(); // expected-note {{instantiation of}}
+ X<B>::StaticFun(); // expected-note {{instantiation of}}
+ X<C>::StaticFun();
+#if __cplusplus < 201103L
+ // expected-note@-2 {{instantiation of}}
+#endif
+ Y<A>::StaticFun(); // expected-note {{instantiation of}}
+ Y<B>::StaticFun(); // expected-note {{instantiation of}}
+ }
+
+ template<typename T, typename U> void value_vs_value() {
+ using T::a; // expected-note {{previous}}
+#if __cplusplus < 201103L
+ // expected-error@-2 {{cannot be used prior to '::'}}
+#endif
+ extern int a(); // expected-error {{different kind of symbol}}
+ a();
+
+ extern int b(); // expected-note {{previous}}
+ using T::b; // expected-error {{different kind of symbol}}
+ b();
+
+ using T::c; // expected-note {{previous}}
+ using U::c; // expected-error-re {{redefinition of 'c'{{$}}}}
+ c();
+ }
+
+ template<typename T, typename U> void value_vs_type() {
+ using T::Xt; // expected-note {{previous}}
+ typedef struct {} Xt; // expected-error {{different kind of symbol}}
+ (void)Xt;
+
+ using T::Xs; // expected-note {{hidden by}}
+ struct Xs {};
+ (void)Xs;
+ Xs xs; // expected-error {{must use 'struct'}}
+
+ using T::Xe; // expected-note {{hidden by}}
+ enum Xe {};
+ (void)Xe;
+ Xe xe; // expected-error {{must use 'enum'}}
+
+ typedef struct {} Yt; // expected-note {{candidate}}
+ using T::Yt; // eypected-error {{different kind of symbol}} expected-note {{candidate}}
+ Yt yt; // expected-error {{ambiguous}}
+
+ struct Ys {};
+ using T::Ys; // expected-note {{hidden by}}
+ (void)Ys;
+ Ys ys; // expected-error {{must use 'struct'}}
+
+ enum Ye {};
+ using T::Ye; // expected-note {{hidden by}}
+ Ye ye; // expected-error {{must use 'enum'}}
+ }
+
+ template<typename T> void type() {
+ // Must be a class member because T:: can only name a class or enum,
+ // and an enum cannot have a type member.
+ using typename T::X; // expected-error {{cannot refer to class member}}
+ }
+
+ namespace N1 { enum E { a, b, c }; }
+ namespace N2 { enum E { a, b, c }; }
+ void g() { value_vs_value<N1::E, N2::E>(); }
+#if __cplusplus < 201103L
+ // expected-note@-2 {{in instantiation of}}
+#endif
+
+#if __cplusplus >= 201402L
+ namespace partial_substitute {
+ template<typename T> auto f() {
+ return [](auto x) {
+ using A = typename T::template U<decltype(x)>;
+ using A::E::e;
+ struct S : A {
+ using A::f;
+ using typename A::type;
+ type f(int) { return e; }
+ };
+ return S();
+ };
+ }
+ enum Enum { e };
+ struct X {
+ template<typename T> struct U {
+ int f(int, int);
+ using type = int;
+ using E = Enum;
+ };
+ };
+ int test() {
+ auto s = f<X>()(0);
+ return s.f(0) + s.f(0, 0);
+ }
+
+ template<typename T, typename U> auto g() {
+ return [](auto x) {
+ using X = decltype(x);
+ struct S : T::template Q<X>, U::template Q<X> {
+ using T::template Q<X>::f;
+ using U::template Q<X>::f;
+ void h() { f(); }
+ void h(int n) { f(n); }
+ };
+ return S();
+ };
+ }
+ struct A { template<typename> struct Q { int f(); }; };
+ struct B { template<typename> struct Q { int f(int); }; };
+ int test2() {
+ auto s = g<A, B>()(0);
+ s.f();
+ s.f(0);
+ s.h();
+ s.h(0);
+ }
+ }
+#endif
+
+ template<typename T, typename U> struct RepeatedMember : T, U {
+ // FIXME: This is the wrong error: we should complain that a member type
+ // cannot be redeclared at class scope.
+ using typename T::type; // expected-note {{candidate}}
+ using typename U::type; // expected-note {{candidate}}
+ type x; // expected-error {{ambiguous}}
+ };
+}
struct S {
static int n;
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
index 027104151ac68..f3e79c0aae44a 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -2,18 +2,18 @@
struct A { typedef int type; };
template<typename T> using X = A; // expected-note {{declared here}}
-struct X<int>* p2; // expected-error {{elaborated type refers to a type alias template}}
+struct X<int>* p2; // expected-error {{type alias template 'X' cannot be referenced with a struct specifier}}
template<typename T> using Id = T; // expected-note {{declared here}}
template<template<typename> class F>
struct Y {
- struct F<int> i; // expected-error {{elaborated type refers to a type alias template}}
+ struct F<int> i; // expected-error {{type alias template 'Id' cannot be referenced with a struct specifier}}
typename F<A>::type j; // ok
// FIXME: don't produce the diagnostic both for the definition and the instantiation.
template<typename T> using U = F<char>; // expected-note 2{{declared here}}
- struct Y<F>::template U<char> k; // expected-error 2{{elaborated type refers to a type alias template}}
+ struct Y<F>::template U<char> k; // expected-error 2{{type alias template 'U' cannot be referenced with a struct specifier}}
typename Y<F>::template U<char> l; // ok
};
template struct Y<Id>; // expected-note {{requested here}}
diff --git a/test/CXX/dcl.decl/dcl.decomp/p2.cpp b/test/CXX/dcl.decl/dcl.decomp/p2.cpp
new file mode 100644
index 0000000000000..211719a7e9c64
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.decomp/p2.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s -Wpedantic
+
+struct X {
+ X(int);
+ X(const X&) = delete;
+};
+
+int array() {
+ static int arr[3] = {};
+ auto [a, b, c] = arr;
+ static_assert(&a != &arr[0]);
+
+ using I3 = int[3];
+ auto [a2, b2, c2] = I3{1, 2, 3};
+
+ using X3 = X[3];
+ auto [a3, b3, c3] = X3{1, 2, 3};
+
+ auto &[d, e] = arr; // expected-error {{type 'int [3]' decomposes into 3 elements, but only 2 names were provided}}
+ auto &[f, g, h, i] = arr; // expected-error {{type 'int [3]' decomposes into 3 elements, but 4 names were provided}}
+
+ auto &[r0, r1, r2] = arr;
+ const auto &[cr0, cr1, cr2] = arr;
+
+ static_assert(&arr[0] == &r0);
+ static_assert(&arr[0] == &cr0);
+
+ using T = int;
+ using T = decltype(r0);
+ using U = const int;
+ using U = decltype(cr0);
+
+ return r1 + cr2;
+}
diff --git a/test/CXX/dcl.decl/dcl.decomp/p3.cpp b/test/CXX/dcl.decl/dcl.decomp/p3.cpp
new file mode 100644
index 0000000000000..b7092e3af0238
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.decomp/p3.cpp
@@ -0,0 +1,232 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+using size_t = decltype(sizeof(0));
+
+struct A { int x, y; };
+struct B { int x, y; };
+
+void no_tuple_size_1() { auto [x, y] = A(); } // ok, decompose elementwise
+
+namespace std { template<typename T> struct tuple_size; }
+void no_tuple_size_2() { auto [x, y] = A(); } // ok, decompose elementwise
+
+struct Bad1 { int a, b; };
+template<> struct std::tuple_size<Bad1> {};
+void no_tuple_size_3() { auto [x, y] = Bad1(); } // expected-error {{cannot decompose this type; 'std::tuple_size<Bad1>::value' is not a valid integral constant expression}}
+
+struct Bad2 {};
+template<> struct std::tuple_size<Bad2> { const int value = 5; };
+void no_tuple_size_4() { auto [x, y] = Bad2(); } // expected-error {{cannot decompose this type; 'std::tuple_size<Bad2>::value' is not a valid integral constant expression}}
+
+template<> struct std::tuple_size<A> { static const int value = 3; };
+template<> struct std::tuple_size<B> { enum { value = 3 }; };
+
+void no_get_1() {
+ {
+ auto [a0, a1] = A(); // expected-error {{decomposes into 3 elements}}
+ auto [b0, b1] = B(); // expected-error {{decomposes into 3 elements}}
+ }
+ auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}}
+}
+
+int get(A);
+
+void no_get_2() {
+ // FIXME: This diagnostic is not great.
+ auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}}
+}
+
+template<int> float &get(A);
+
+void no_tuple_element_1() {
+ auto [a0, a1, a2] = A(); // expected-error-re {{'std::tuple_element<0U{{L*}}, A>::type' does not name a type}} expected-note {{in implicit}}
+}
+
+namespace std { template<size_t, typename> struct tuple_element; } // expected-note 2{{here}}
+
+void no_tuple_element_2() {
+ auto [a0, a1, a2] = A(); // expected-error {{implicit instantiation of undefined template 'std::tuple_element<0, A>'}} expected-note {{in implicit}}
+}
+
+template<> struct std::tuple_element<0, A> { typedef float type; };
+
+void no_tuple_element_3() {
+ auto [a0, a1, a2] = A(); // expected-error {{implicit instantiation of undefined template 'std::tuple_element<1, A>'}} expected-note {{in implicit}}
+}
+
+template<> struct std::tuple_element<1, A> { typedef float &type; };
+template<> struct std::tuple_element<2, A> { typedef const float &type; };
+
+template<int N> auto get(B) -> int (&)[N + 1];
+template<int N> struct std::tuple_element<N, B> { typedef int type[N +1 ]; };
+
+template<typename T> struct std::tuple_size<const T> : std::tuple_size<T> {};
+template<size_t N, typename T> struct std::tuple_element<N, const T> {
+ typedef const typename std::tuple_element<N, T>::type type;
+};
+
+void referenced_type() {
+ auto [a0, a1, a2] = A();
+ auto [b0, b1, b2] = B();
+
+ A a;
+ B b;
+ auto &[ar0, ar1, ar2] = a;
+ auto &[br0, br1, br2] = b;
+
+ auto &&[arr0, arr1, arr2] = A();
+ auto &&[brr0, brr1, brr2] = B();
+
+ const auto &[acr0, acr1, acr2] = A();
+ const auto &[bcr0, bcr1, bcr2] = B();
+
+
+ using Float = float;
+ using Float = decltype(a0);
+ using Float = decltype(ar0);
+ using Float = decltype(arr0);
+
+ using ConstFloat = const float;
+ using ConstFloat = decltype(acr0);
+
+ using FloatRef = float&;
+ using FloatRef = decltype(a1);
+ using FloatRef = decltype(ar1);
+ using FloatRef = decltype(arr1);
+ using FloatRef = decltype(acr1);
+
+ using ConstFloatRef = const float&;
+ using ConstFloatRef = decltype(a2);
+ using ConstFloatRef = decltype(ar2);
+ using ConstFloatRef = decltype(arr2);
+ using ConstFloatRef = decltype(acr2);
+
+
+ using Int1 = int[1];
+ using Int1 = decltype(b0);
+ using Int1 = decltype(br0);
+ using Int1 = decltype(brr0);
+
+ using ConstInt1 = const int[1];
+ using ConstInt1 = decltype(bcr0);
+
+ using Int2 = int[2];
+ using Int2 = decltype(b1);
+ using Int2 = decltype(br1);
+ using Int2 = decltype(brr1);
+
+ using ConstInt2 = const int[2];
+ using ConstInt2 = decltype(bcr1);
+
+ using Int3 = int[3];
+ using Int3 = decltype(b2);
+ using Int3 = decltype(br2);
+ using Int3 = decltype(brr2);
+
+ using ConstInt3 = const int[3];
+ using ConstInt3 = decltype(bcr2);
+}
+
+struct C { template<int> int get(); };
+template<> struct std::tuple_size<C> { static const int value = 1; };
+template<> struct std::tuple_element<0, C> { typedef int type; };
+
+int member_get() {
+ auto [c] = C();
+ using T = int;
+ using T = decltype(c);
+ return c;
+}
+
+struct D { template<int> struct get {}; }; // expected-note {{declared here}}
+template<> struct std::tuple_size<D> { static const int value = 1; };
+template<> struct std::tuple_element<0, D> { typedef D::get<0> type; };
+void member_get_class_template() {
+ auto [d] = D(); // expected-error {{cannot refer to member 'get' in 'D' with '.'}} expected-note {{in implicit init}}
+}
+
+struct E { int get(); };
+template<> struct std::tuple_size<E> { static const int value = 1; };
+template<> struct std::tuple_element<0, E> { typedef int type; };
+void member_get_non_template() {
+ // FIXME: This diagnostic is not very good.
+ auto [e] = E(); // expected-error {{no member named 'get'}} expected-note {{in implicit init}}
+}
+
+namespace ADL {
+ struct X {};
+};
+template<int> int get(ADL::X);
+template<> struct std::tuple_size<ADL::X> { static const int value = 1; };
+template<> struct std::tuple_element<0, ADL::X> { typedef int type; };
+void adl_only_bad() {
+ auto [x] = ADL::X(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit init}}
+}
+
+template<typename ElemType, typename GetTypeLV, typename GetTypeRV>
+struct wrap {
+ template<size_t> GetTypeLV get() &;
+ template<size_t> GetTypeRV get() &&;
+};
+template<typename ET, typename GTL, typename GTR>
+struct std::tuple_size<wrap<ET, GTL, GTR>> {
+ static const int value = 1;
+};
+template<typename ET, typename GTL, typename GTR>
+struct std::tuple_element<0, wrap<ET, GTL, GTR>> {
+ using type = ET;
+};
+
+template<typename T> T &lvalue();
+
+void test_value_category() {
+ // If the declared variable is an lvalue reference, the operand to get is an
+ // lvalue. Otherwise it's an xvalue.
+ { auto [a] = wrap<int, void, int>(); }
+ { auto &[a] = lvalue<wrap<int, int, void>>(); }
+ { auto &&[a] = wrap<int, void, int>(); }
+ // If the initializer (call to get) is an lvalue, the binding is an lvalue
+ // reference to the element type. Otherwise it's an rvalue reference to the
+ // element type.
+ { auto [a] = wrap<int, void, int&>(); }
+ { auto [a] = wrap<int&, void, int&>(); }
+ { auto [a] = wrap<int&&, void, int&>(); } // ok, reference collapse to int&
+
+ { auto [a] = wrap<int, void, int&&>(); }
+ { auto [a] = wrap<int&, void, int&&>(); } // expected-error {{non-const lvalue reference to type 'int' cannot bind}} expected-note {{in implicit}}
+ { auto [a] = wrap<const int&, void, int&&>(); }
+ { auto [a] = wrap<int&&, void, int&&>(); }
+
+ { auto [a] = wrap<int, void, float&>(); } // expected-error {{cannot bind}} expected-note {{implicit}}
+ { auto [a] = wrap<const int, void, float&>(); } // ok, const int &a can bind to float
+ { auto [a] = wrap<int, void, float>(); } // ok, int &&a can bind to float
+}
+
+namespace constant {
+ struct Q {};
+ template<int N> constexpr int get(Q &&) { return N * N; }
+}
+template<> struct std::tuple_size<constant::Q> { static const int value = 3; };
+template<int N> struct std::tuple_element<N, constant::Q> { typedef int type; };
+namespace constant {
+ Q q;
+ // This creates and lifetime-extends a temporary to hold the result of each get() call.
+ auto [a, b, c] = q; // expected-note {{temporary}}
+ static_assert(a == 0); // expected-error {{constant expression}} expected-note {{temporary}}
+
+ constexpr bool f() {
+ auto [a, b, c] = q;
+ return a == 0 && b == 1 && c == 4;
+ }
+ static_assert(f());
+
+ constexpr int g() {
+ int *p = nullptr;
+ {
+ auto [a, b, c] = q;
+ p = &c;
+ }
+ return *p; // expected-note {{read of object outside its lifetime}}
+ }
+ static_assert(g() == 4); // expected-error {{constant}} expected-note {{in call to 'g()'}}
+}
diff --git a/test/CXX/dcl.decl/dcl.decomp/p4.cpp b/test/CXX/dcl.decl/dcl.decomp/p4.cpp
new file mode 100644
index 0000000000000..c461eb6f54b72
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.decomp/p4.cpp
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 -std=c++1z -verify -triple i686-linux-gnu %s
+
+template<typename T, typename U> struct same;
+template<typename T> struct same<T, T> { ~same(); };
+
+struct Empty {};
+
+struct A {
+ int a;
+};
+
+namespace NonPublicMembers {
+ struct NonPublic1 {
+ protected:
+ int a; // expected-note {{declared protected here}}
+ };
+
+ struct NonPublic2 {
+ private:
+ int a; // expected-note 2{{declared private here}}
+ };
+
+ struct NonPublic3 : private A {}; // expected-note {{constrained by private inheritance}}
+
+ struct NonPublic4 : NonPublic2 {};
+
+ void test() {
+ auto [a1] = NonPublic1(); // expected-error {{cannot decompose non-public member 'a' of 'NonPublicMembers::NonPublic1'}}
+ auto [a2] = NonPublic2(); // expected-error {{cannot decompose non-public member 'a' of 'NonPublicMembers::NonPublic2'}}
+ auto [a3] = NonPublic3(); // expected-error {{cannot decompose members of non-public base class 'A' of 'NonPublic3'}}
+ auto [a4] = NonPublic4(); // expected-error {{cannot decompose non-public member 'a' of 'NonPublicMembers::NonPublic4'}}
+ }
+}
+
+namespace AnonymousMember {
+ struct Struct {
+ struct { // expected-note {{declared here}}
+ int i;
+ };
+ };
+
+ struct Union {
+ union { // expected-note {{declared here}}
+ int i;
+ };
+ };
+
+ void test() {
+ auto [a1] = Struct(); // expected-error {{cannot decompose class type 'AnonymousMember::Struct' because it has an anonymous struct member}}
+ auto [a2] = Union(); // expected-error {{cannot decompose class type 'AnonymousMember::Union' because it has an anonymous union member}}
+ }
+}
+
+namespace MultipleClasses {
+ struct B : A {
+ int a;
+ };
+
+ struct C { int a; };
+ struct D : A, C {};
+
+ struct E : virtual A {};
+ struct F : A, E {}; // expected-warning {{direct base 'A' is inaccessible due to ambiguity}}
+
+ struct G : virtual A {};
+ struct H : E, G {};
+
+ struct I { int i; };
+ struct J : I {};
+ struct K : I, virtual J {}; // expected-warning {{direct base 'MultipleClasses::I' is inaccessible due to ambiguity}}
+
+ struct L : virtual J {};
+ struct M : virtual J, L {};
+
+ void test() {
+ auto [b] = B(); // expected-error {{cannot decompose class type 'B': both it and its base class 'A' have non-static data members}}
+ auto [d] = D(); // expected-error {{cannot decompose class type 'D': its base classes 'A' and 'MultipleClasses::C' have non-static data members}}
+ auto [e] = E();
+ auto [f] = F(); // expected-error-re {{cannot decompose members of ambiguous base class 'A' of 'F':{{.*}}struct MultipleClasses::F -> struct A{{.*}}struct MultipleClasses::F -> struct MultipleClasses::E -> struct A}}
+ auto [h] = H(); // ok, only one (virtual) base subobject even though there are two paths to it
+ auto [k] = K(); // expected-error {{cannot decompose members of ambiguous base class 'MultipleClasses::I'}}
+ auto [m] = M(); // ok, all paths to I are through the same virtual base subobject J
+
+ same<decltype(m), int>();
+ }
+}
+
+namespace BindingTypes {
+ struct A {
+ int i = 0;
+ int &r = i;
+ const float f = i;
+ mutable volatile int mvi;
+ };
+ void e() {
+ auto [i,r,f,mvi] = A();
+
+ same<decltype(i), int>();
+ same<decltype(r), int&>();
+ same<decltype(f), const float>();
+ same<decltype(mvi), volatile int>();
+
+ same<decltype((i)), int&>();
+ same<decltype((r)), int&>();
+ same<decltype((f)), const float&>();
+ same<decltype((mvi)), volatile int&>();
+ }
+ void f() {
+ auto &&[i,r,f,mvi] = A();
+
+ same<decltype(i), int>();
+ same<decltype(r), int&>();
+ same<decltype(f), const float>();
+ same<decltype(mvi), volatile int>();
+
+ same<decltype((i)), int&>();
+ same<decltype((r)), int&>();
+ same<decltype((f)), const float&>();
+ same<decltype((mvi)), volatile int&>();
+ }
+ void g() {
+ const auto [i,r,f,mvi] = A();
+
+ same<decltype(i), const int>();
+ same<decltype(r), int&>();
+ same<decltype(f), const float>();
+ same<decltype(mvi), volatile int>(); // not 'const volatile int', per expected resolution of DRxxx
+
+ same<decltype((i)), const int&>();
+ same<decltype((r)), int&>();
+ same<decltype((f)), const float&>();
+ same<decltype((mvi)), volatile int&>(); // not 'const volatile int&', per expected resolution of DRxxx
+ }
+ void h() {
+ typedef const A CA;
+ auto &[i,r,f,mvi] = CA(); // type of var is 'const A &'
+
+ same<decltype(i), const int>(); // not 'int', per expected resolution of DRxxx
+ same<decltype(r), int&>();
+ same<decltype(f), const float>();
+ same<decltype(mvi), volatile int>(); // not 'const volatile int', per expected resolution of DRxxx
+
+ same<decltype((i)), const int&>(); // not 'int&', per expected resolution of DRxxx
+ same<decltype((r)), int&>();
+ same<decltype((f)), const float&>();
+ same<decltype((mvi)), volatile int&>(); // not 'const volatile int&', per expected resolution of DRxxx
+ }
+ struct B {
+ mutable int i;
+ };
+ void mut() {
+ auto [i] = B();
+ const auto [ci] = B();
+ volatile auto [vi] = B();
+ same<decltype(i), int>();
+ same<decltype(ci), int>();
+ same<decltype(vi), volatile int>();
+ }
+}
+
+namespace Bitfield {
+ struct S { unsigned long long x : 4, y : 32; int z; }; // expected-note 2{{here}}
+ int f(S s) {
+ auto [a, b, c] = s;
+ unsigned long long &ra = a; // expected-error {{bit-field 'x'}}
+ unsigned long long &rb = b; // expected-error {{bit-field 'y'}}
+ int &rc = c;
+
+ // the type of the binding is the type of the field
+ same<decltype(a), unsigned long long>();
+ same<decltype(b), unsigned long long>();
+
+ // the type of the expression is an lvalue of the field type
+ // (even though a reference can't bind to the field)
+ same<decltype((a)), unsigned long long&>();
+ same<decltype((b)), unsigned long long&>();
+
+ // the expression promotes to a type large enough to hold the result
+ same<decltype(+a), int>();
+ same<decltype(+b), unsigned int>();
+ return rc;
+ }
+}
+
+namespace Constexpr {
+ struct Q { int a, b; constexpr Q() : a(1), b(2) {} };
+ constexpr Q q;
+ auto &[qa, qb] = q;
+ static_assert(&qa == &q.a && &qb == &q.b);
+ static_assert(qa == 1 && qb == 2);
+}
+
+namespace std_example {
+ struct S { int x1 : 2; volatile double y1; };
+ S f();
+ const auto [x, y] = f();
+
+ same<decltype((x)), const int&> same1;
+ same<decltype((y)), const volatile double&> same2;
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
index 40f6431e3ddb8..7a92e7a13d959 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
@@ -122,3 +122,39 @@ struct DefaultedAggr {
~DefaultedAggr() = default;
};
DefaultedAggr da = { 42 } ;
+
+struct ExplicitDefaultedAggr {
+ int n;
+ explicit ExplicitDefaultedAggr() = default; // expected-note {{candidate}}
+ ExplicitDefaultedAggr(const ExplicitDefaultedAggr &) = default; // expected-note {{candidate}}
+ ExplicitDefaultedAggr(ExplicitDefaultedAggr &&) = default; // expected-note {{candidate}}
+};
+ExplicitDefaultedAggr eda = { 42 }; // expected-error {{no matching constructor}}
+ExplicitDefaultedAggr eda2{};
+
+struct DefaultedBase {
+ int n;
+ DefaultedBase() = default; // expected-note 0+ {{candidate}}
+ DefaultedBase(DefaultedBase const&) = default; // expected-note 0+ {{candidate}}
+ DefaultedBase(DefaultedBase &&) = default; // expected-note 0+ {{candidate}}
+};
+
+struct InheritingConstructors : DefaultedBase { // expected-note 3 {{candidate}}
+ using DefaultedBase::DefaultedBase; // expected-note 2 {{inherited here}}
+};
+InheritingConstructors ic = { 42 }; // expected-error {{no matching constructor}}
+
+struct NonInheritingConstructors : DefaultedBase {}; // expected-note 0+ {{candidate}}
+NonInheritingConstructors nic = { 42 };
+#if __cplusplus <= 201402L
+// expected-error@-2 {{no matching constructor}}
+#endif
+
+struct NonAggrBase {
+ NonAggrBase(int) {}
+};
+struct HasNonAggrBase : NonAggrBase {}; // expected-note 0+ {{candidate}}
+HasNonAggrBase hnab = {42};
+#if __cplusplus <= 201402L
+// expected-error@-2 {{no matching constructor}}
+#endif
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp
index 299611ba73593..d66494fa2c2c4 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// Verify that the appropriate fixits are emitted for narrowing conversions in
// initializer lists.
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4.cpp
new file mode 100644
index 0000000000000..1a3732d99ea6f
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+void f() noexcept;
+void (&r)() = f;
+void (&s)() noexcept = r; // expected-error {{cannot bind}}
+
+void (&cond1)() noexcept = true ? r : f; // expected-error {{cannot bind}}
+void (&cond2)() noexcept = true ? f : r; // expected-error {{cannot bind}}
+// FIXME: Strictly, the rules in p4 don't allow this, because the operand types
+// are not of the same type other than cv-qualifiers, but we consider that to
+// be a defect, and instead allow reference-compatible types here.
+void (&cond3)() = true ? r : f;
+void (&cond4)() = true ? f : r;
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
index f86b24e992590..7a5caef36e737 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -Wbind-to-temporary-copy -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++03 -fdiagnostics-show-option -Wbind-to-temporary-copy -verify %s
// C++03 requires that we check for a copy constructor when binding a
// reference to a temporary, since we are allowed to make a copy, Even
@@ -19,7 +19,7 @@ private:
};
struct X3 {
- X3();
+ X3(); // expected-note{{requires 0 arguments, but 1 was provided}}
private:
X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}}
@@ -42,8 +42,8 @@ struct X4 {
// Check for "dangerous" default arguments that could cause recursion.
struct X5 {
- X5();
- X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}}
+ X5(); // expected-note {{requires 0 arguments}}
+ X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} expected-note {{requires 2 arguments}}
};
void g1(const X1&);
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
index be1113d47e3a6..052349c8e2e00 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
-// CHECK: example0
+// CHECK-LABEL: example0
void example0() {
double d = 2.0;
// CHECK: VarDecl{{.*}}rd 'double &'
@@ -14,14 +14,15 @@ void example0() {
struct A { };
struct B : A { } b;
-// CHECK: example1
+// CHECK-LABEL: example1
void example1() {
// CHECK: VarDecl{{.*}}ra 'struct A &'
// CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
A &ra = b;
// CHECK: VarDecl{{.*}}rca 'const struct A &'
- // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp>
- // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)>
+ // CHECK-NOT: MaterializeTemporaryExpr
+ // CHECK: ImplicitCastExpr{{.*}}'const struct B' lvalue <NoOp>
const A& rca = b;
}
@@ -31,21 +32,23 @@ struct X {
operator B();
} x;
-// CHECK: example2
+// CHECK-LABEL: example2
void example2() {
// CHECK: VarDecl{{.*}}rca 'const struct A &'
- // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
- // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)>
+ // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B'
+ // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp>
// CHECK: CallExpr{{.*}}B
const A &rca = f();
// CHECK: VarDecl{{.*}}r 'const struct A &'
- // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
- // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)>
+ // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B'
+ // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp>
// CHECK: CXXMemberCallExpr{{.*}}'struct B'
const A& r = x;
}
-// CHECK: example3
+// CHECK-LABEL: example3
void example3() {
// CHECK: VarDecl{{.*}}rcd2 'const double &'
// CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
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
index 263f661208c5a..e775e8f0e3cc5 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -41,7 +41,7 @@ namespace PR6066 {
namespace test3 {
struct A {
- unsigned bitX : 4; // expected-note 4 {{bit-field is declared here}}
+ unsigned bitX : 4; // expected-note 3 {{bit-field is declared here}}
unsigned bitY : 4; // expected-note {{bit-field is declared here}}
unsigned var;
@@ -50,7 +50,7 @@ namespace test3 {
void test(A *a) {
unsigned &t0 = a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
- unsigned &t1 = (unsigned&) a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
+ unsigned &t1 = (unsigned&) a->bitX; // expected-error {{C-style cast from bit-field lvalue to reference type 'unsigned int &'}}
unsigned &t2 = const_cast<unsigned&>(a->bitX); // expected-error {{const_cast from bit-field lvalue to reference type 'unsigned int &'}}
unsigned &t3 = (a->foo(), a->bitX); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}}
unsigned &t4 = (a->var ? a->bitX : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}}
diff --git a/test/CXX/dcl.decl/dcl.init/p5.cpp b/test/CXX/dcl.decl/dcl.init/p5.cpp
index e7ccb2ec41e68..76e53edf33574 100644
--- a/test/CXX/dcl.decl/dcl.init/p5.cpp
+++ b/test/CXX/dcl.decl/dcl.init/p5.cpp
@@ -1,3 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify %s
// A program that calls for default-initialization or value-initialization of
@@ -5,6 +7,11 @@
// cv-unqualified version of T is used for these definitions of
// zero-initialization, default-initialization, and value-initialization.
+typedef int &IR;
+IR r; // expected-error {{declaration of reference variable 'r' requires an initializer}}
+int n = IR(); // expected-error {{reference to type 'int' requires an initializer}}
+
+#if __cplusplus < 201103L
struct S { // expected-error {{implicit default constructor for 'S' must explicitly initialize the reference member}}
int &x; // expected-note {{declared here}} expected-error 3{{reference to type 'int' requires an initializer}}
};
@@ -22,6 +29,25 @@ struct U {
T t[3]; // expected-note {{in value-initialization of type 'T' here}}
};
U u = U(); // expected-note {{in value-initialization of type 'U' here}}
+#else
+struct S {
+ int &x; // expected-note 4{{because field 'x' of reference type 'int &' would not be initialized}}
+};
+S s; // expected-error {{deleted default constructor}}
+S f() {
+ return S(); // expected-error {{deleted default constructor}}
+}
+
+struct T
+ : S { // expected-note 2{{because base class 'S' has a deleted default constructor}}
+};
+T t = T(); // expected-error {{deleted default constructor}}
+
+struct U {
+ T t[3]; // expected-note {{because field 't' has a deleted default constructor}}
+};
+U u = U(); // expected-error {{deleted default constructor}}
+#endif
// Ensure that we handle C++11 in-class initializers properly as an extension.
// In this case, there is no user-declared default constructor, so we
@@ -29,20 +55,19 @@ U u = U(); // expected-note {{in value-initialization of type 'U' here}}
// constructor call anyway, because the default constructor is not trivial.
struct V {
int n;
- int &r = n; // expected-warning {{C++11}}
+ int &r = n; // expected-warning 0-1{{C++11}}
};
V v = V(); // ok
struct W {
int n;
- S s = { n }; // expected-warning {{C++11}}
+ S s = { n }; // expected-warning 0-1{{C++11}}
};
W w = W(); // ok
// Ensure we're not faking this up by making the default constructor
// non-trivial.
-#define static_assert(B, S) typedef int assert_failed[(B) ? 1 : -1];
-static_assert(__has_trivial_constructor(S), "");
-static_assert(__has_trivial_constructor(T), "");
-static_assert(__has_trivial_constructor(U), "");
-static_assert(!__has_trivial_constructor(V), "");
-static_assert(!__has_trivial_constructor(W), "");
+_Static_assert(__has_trivial_constructor(S), "");
+_Static_assert(__has_trivial_constructor(T), "");
+_Static_assert(__has_trivial_constructor(U), "");
+_Static_assert(!__has_trivial_constructor(V), "");
+_Static_assert(!__has_trivial_constructor(W), "");
diff --git a/test/CXX/dcl.decl/dcl.init/p7.cpp b/test/CXX/dcl.decl/dcl.init/p7.cpp
index 03216f4c28ac5..1c1d793e8a5e6 100644
--- a/test/CXX/dcl.decl/dcl.init/p7.cpp
+++ b/test/CXX/dcl.decl/dcl.init/p7.cpp
@@ -12,3 +12,5 @@ struct B : NotAggregateBase {
explicit B() = default; // expected-note {{here}}
};
B b = {}; // expected-error {{chosen constructor is explicit}}
+B b2{};
+B b3;
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
index cec747e1d6054..d93cc8b90874d 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s
void f0() &; // expected-error {{non-member function cannot have '&' qualifier}}
void f1() &&; // expected-error {{non-member function cannot have '&&' qualifier}}
@@ -58,3 +59,16 @@ template<typename T> struct pass {
};
pass<func_type_lvalue> pass0;
pass<func_type_lvalue> pass1;
+
+template<typename T, typename U> struct is_same { static const bool value = false; };
+template<typename T> struct is_same<T, T> { static const bool value = true; };
+constexpr bool cxx1z = __cplusplus > 201402L;
+
+void noexcept_true() noexcept(true);
+void noexcept_false() noexcept(false);
+using func_type_noexcept_true = wrap<decltype(noexcept_true)>;
+using func_type_noexcept_false = wrap<decltype(noexcept_false)>;
+static_assert(is_same<func_type_noexcept_false, func_type_noexcept_true>::value == !cxx1z, "");
+static_assert(is_same<func_type_noexcept_false::val, func_type_noexcept_true::val>::value == !cxx1z, "");
+static_assert(is_same<func_type_noexcept_false::ptr, func_type_noexcept_true::ptr>::value == !cxx1z, "");
+static_assert(is_same<func_type_noexcept_false::ref, func_type_noexcept_true::ref>::value == !cxx1z, "");
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp
index 3bb6701b32e1a..c988b6aba57e5 100644
--- a/test/CXX/drs/dr0xx.cpp
+++ b/test/CXX/drs/dr0xx.cpp
@@ -248,7 +248,7 @@ namespace dr20 { // dr20: yes
private:
X(const X&); // expected-note {{here}}
};
- X f();
+ X &f();
X x = f(); // expected-error {{private}}
}
@@ -276,20 +276,39 @@ namespace dr23 { // dr23: yes
namespace dr25 { // dr25: yes
struct A {
- void f() throw(int);
+ void f() throw(int); // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
};
- void (A::*f)() throw (int);
- void (A::*g)() throw () = f; // expected-error {{is not superset of source}}
+ void (A::*f)() throw (int); // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
+ void (A::*g)() throw () = f;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{is not superset of source}}
+#else
+ // expected-error@-4 {{different exception specifications}}
+#endif
void (A::*g2)() throw () = 0;
- void (A::*h)() throw (int, char) = f;
- void (A::*i)() throw () = &A::f; // expected-error {{is not superset of source}}
+ void (A::*h)() throw (int, char) = f; // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
+ void (A::*i)() throw () = &A::f;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{is not superset of source}}
+#else
+ // expected-error@-4 {{different exception specifications}}
+#endif
void (A::*i2)() throw () = 0;
- void (A::*j)() throw (int, char) = &A::f;
+ void (A::*j)() throw (int, char) = &A::f; // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
void x() {
- // FIXME: Don't produce the second error here.
- g2 = f; // expected-error {{is not superset}} expected-error {{incompatible}}
+ g2 = f;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{is not superset of source}}
+#else
+ // expected-error@-4 {{different exception specifications}}
+#endif
h = f;
- i2 = &A::f; // expected-error {{is not superset}} expected-error {{incompatible}}
+ i2 = &A::f;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{is not superset of source}}
+#else
+ // expected-error@-4 {{different exception specifications}}
+#endif
j = &A::f;
}
}
@@ -297,8 +316,15 @@ namespace dr25 { // dr25: yes
namespace dr26 { // dr26: yes
struct A { A(A, const A & = A()); }; // expected-error {{must pass its first argument by reference}}
struct B {
- B(); // expected-note {{candidate}}
- B(const B &, B = B()); // expected-error {{no matching constructor}} expected-note {{candidate}} expected-note {{here}}
+ B(); // expected-note 0-1{{candidate}}
+ B(const B &, B = B());
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{no matching constructor}} expected-note@-2 {{candidate}} expected-note@-2 {{here}}
+#endif
+ };
+ struct C {
+ static C &f();
+ C(const C &, C = f()); // expected-error {{no matching constructor}} expected-note {{candidate}} expected-note {{here}}
};
}
@@ -307,7 +333,7 @@ namespace dr27 { // dr27: yes
E &m = true ? n : n;
}
-// dr28: na
+// dr28: na lib
namespace dr29 { // dr29: 3.4
void dr29_f0(); // expected-note {{here}}
@@ -643,25 +669,33 @@ namespace dr58 { // dr58: yes
namespace dr59 { // dr59: yes
template<typename T> struct convert_to { operator T() const; };
- struct A {}; // expected-note 2{{volatile qualifier}}
- struct B : A {}; // expected-note 2{{volatile qualifier}}
-#if __cplusplus >= 201103L // move constructors
- // expected-note@-3 2{{volatile qualifier}}
- // expected-note@-3 2{{volatile qualifier}}
-#endif
+ struct A {}; // expected-note 5+{{candidate}}
+ struct B : A {}; // expected-note 0+{{candidate}}
A a1 = convert_to<A>();
A a2 = convert_to<A&>();
A a3 = convert_to<const A>();
- A a4 = convert_to<const volatile A>(); // expected-error {{no viable}}
+ A a4 = convert_to<const volatile A>();
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{no viable}}
+#endif
A a5 = convert_to<const volatile A&>(); // expected-error {{no viable}}
B b1 = convert_to<B>();
B b2 = convert_to<B&>();
B b3 = convert_to<const B>();
- B b4 = convert_to<const volatile B>(); // expected-error {{no viable}}
+ B b4 = convert_to<const volatile B>();
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{no viable}}
+#endif
B b5 = convert_to<const volatile B&>(); // expected-error {{no viable}}
+ A c1 = convert_to<B>();
+ A c2 = convert_to<B&>();
+ A c3 = convert_to<const B>();
+ A c4 = convert_to<const volatile B>(); // expected-error {{no viable}}
+ A c5 = convert_to<const volatile B&>(); // expected-error {{no viable}}
+
int n1 = convert_to<int>();
int n2 = convert_to<int&>();
int n3 = convert_to<const int>();
@@ -901,14 +935,17 @@ namespace dr84 { // dr84: yes
struct A { operator B() const; };
struct C {};
struct B {
- B(B&); // expected-note {{candidate}}
- B(C);
+ B(B&); // expected-note 0-1{{candidate}}
+ B(C); // expected-note 0-1{{no known conversion from 'dr84::B' to 'dr84::C'}}
operator C() const;
};
A a;
// Cannot use B(C) / operator C() pair to construct the B from the B temporary
- // here.
- B b = a; // expected-error {{no viable}}
+ // here. In C++1z, we initialize the B object directly using 'A::operator B()'.
+ B b = a;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{no viable}}
+#endif
}
namespace dr85 { // dr85: yes
@@ -942,10 +979,11 @@ namespace dr85 { // dr85: yes
// dr86: dup 446
namespace dr87 { // dr87: no
+ // FIXME: Superseded by dr1975
template<typename T> struct X {};
// FIXME: This is invalid.
X<void() throw()> x;
- // ... but this is valid.
+ // This is valid under dr87 but not under dr1975.
X<void(void() throw())> y;
}
@@ -994,24 +1032,40 @@ namespace dr91 { // dr91: yes
int k = f(U());
}
-namespace dr92 { // FIXME: Issue is still open.
- void f() throw(int, float);
- void (*p)() throw(int) = &f; // expected-error {{target exception specification is not superset of source}}
- void (*q)() throw(int);
- void (**pp)() throw() = &q; // expected-error {{exception specifications are not allowed}}
+namespace dr92 { // dr92: 4.0 c++17
+ void f() throw(int, float); // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
+ void (*p)() throw(int) = &f; // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{target exception specification is not superset of source}}
+#else
+ // expected-warning@-4 {{target exception specification is not superset of source}}
+#endif
+ void (*q)() throw(int); // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
+ void (**pp)() throw() = &q;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{exception specifications are not allowed}}
+#else
+ // expected-error@-4 {{cannot initialize}}
+#endif
- void g(void() throw());
- void h() {
- g(f); // expected-error {{is not superset}}
- g(q); // expected-error {{is not superset}}
+ void g(void() throw()); // expected-note 0-2 {{no known conversion}} expected-warning 0-1{{mangled name of 'g' will change in C++17}}
+ void h() throw() {
+ g(f); // expected-error-re {{{{is not superset|no matching function}}}}
+ g(q); // expected-error-re {{{{is not superset|no matching function}}}}
}
// Prior to C++17, this is OK because the exception specification is not
// considered in this context. In C++17, we *do* perform an implicit
- // conversion (which performs initialization), but we convert to the type of
- // the template parameter, which does not include the exception specification.
+ // conversion (which performs initialization), and the exception specification
+ // is part of the type of the parameter, so this is invalid.
template<void() throw()> struct X {};
- X<&f> xp; // ok
+ X<&f> xp;
+#if __cplusplus > 201402L
+ // expected-error@-2 {{not implicitly convertible}}
+#endif
+
+ template<void() throw(int)> struct Y {}; // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
+ Y<&h> yp; // ok
}
// dr93: na
diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp
index a1d7ef67c66d9..e11e796165e22 100644
--- a/test/CXX/drs/dr10xx.cpp
+++ b/test/CXX/drs/dr10xx.cpp
@@ -3,8 +3,6 @@
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// expected-no-diagnostics
-
namespace std {
__extension__ typedef __SIZE_TYPE__ size_t;
@@ -32,6 +30,18 @@ namespace dr1048 { // dr1048: 3.6
#endif
}
+namespace dr1054 { // dr1054: no
+ // FIXME: Test is incomplete.
+ struct A {} volatile a;
+ void f() {
+ // FIXME: This is wrong: an lvalue-to-rvalue conversion is applied here,
+ // which copy-initializes a temporary from 'a'. Therefore this is
+ // ill-formed because A does not have a volatile copy constructor.
+ // (We might want to track this aspect under dr1383 instead?)
+ a; // expected-warning {{assign into a variable to force a volatile load}}
+ }
+}
+
namespace dr1070 { // dr1070: 3.5
#if __cplusplus >= 201103L
struct A {
diff --git a/test/CXX/drs/dr118.cpp b/test/CXX/drs/dr118.cpp
new file mode 100644
index 0000000000000..58aa3912c8010
--- /dev/null
+++ b/test/CXX/drs/dr118.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -pedantic-errors -emit-llvm -o - | FileCheck %s --implicit-check-not " call "
+
+// dr118: yes
+
+struct S {
+ virtual void f();
+};
+void (S::*pmf)();
+
+// CHECK-LABEL: define {{.*}} @_Z1g
+void g(S *sp) {
+ // CHECK: call void %
+ sp->f(); // 1: polymorphic
+ // CHECK: call void @
+ sp->S::f(); // 2: non-polymorphic
+ // CHECK: call void @
+ (sp->S::f)(); // 3: non-polymorphic
+ // CHECK: call void %
+ (sp->*pmf)(); // 4: polymorphic
+ // CHECK: call void %
+ (sp->*&S::f)(); // 5: polymorphic
+}
+
diff --git a/test/CXX/drs/dr12xx.cpp b/test/CXX/drs/dr12xx.cpp
index 048c21acde568..72d8d683ab7a7 100644
--- a/test/CXX/drs/dr12xx.cpp
+++ b/test/CXX/drs/dr12xx.cpp
@@ -3,7 +3,16 @@
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// expected-no-diagnostics
+namespace dr1213 { // dr1213: 4.0
+#if __cplusplus >= 201103L
+ using T = int[3];
+ int &&r = T{}[1];
+
+ using T = decltype((T{}));
+ using U = decltype((T{}[2]));
+ using U = int &&;
+#endif
+}
namespace dr1250 { // dr1250: 3.9
struct Incomplete;
@@ -16,3 +25,29 @@ struct Derived : Base {
virtual Incomplete *meow();
};
} // dr1250
+
+namespace dr1295 { // dr1295: 4.0
+ struct X {
+ unsigned bitfield : 4;
+ };
+
+ X x = {1};
+
+ unsigned const &r1 = static_cast<X &&>(x).bitfield; // expected-error 0-1{{C++11}}
+ unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); // expected-error 0-1{{C++11}}
+
+ template<unsigned &r> struct Y {};
+ Y<x.bitfield> y;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{does not refer to any declaration}} expected-note@-3 {{here}}
+#else
+ // expected-error@-4 {{refers to subobject}}
+#endif
+
+#if __cplusplus >= 201103L
+ const unsigned other = 0;
+ using T = decltype(true ? other : x.bitfield);
+ using T = unsigned;
+#endif
+}
+
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
index 8c3e7f2a04ca1..28bebcbb607e6 100644
--- a/test/CXX/drs/dr13xx.cpp
+++ b/test/CXX/drs/dr13xx.cpp
@@ -3,6 +3,136 @@
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+namespace dr1315 { // dr1315: partial
+ template <int I, int J> struct A {};
+ template <int I> // expected-note {{non-deducible template parameter 'I'}}
+ struct A<I + 5, I * 2> {}; // expected-error {{contains a template parameter that cannot be deduced}}
+ template <int I> struct A<I, I> {};
+
+ template <int I, int J, int K> struct B;
+ template <int I, int K> struct B<I, I * 2, K> {}; // expected-note {{matches}}
+ B<1, 2, 3> b1;
+
+ // Multiple declarations with the same dependent expression are equivalent
+ // for partial ordering purposes.
+ template <int I> struct B<I, I * 2, 2> { typedef int type; };
+ B<1, 2, 2>::type b2;
+
+ // Multiple declarations with differing dependent expressions are unordered.
+ template <int I, int K> struct B<I, I + 1, K> {}; // expected-note {{matches}}
+ B<1, 2, 4> b3; // expected-error {{ambiguous}}
+
+ // FIXME: Under dr1315, this is perhaps valid, but that is not clear: this
+ // fails the "more specialized than the primary template" test because the
+ // dependent type of T::value is not the same as 'int'.
+ // A core issue will be opened to decide what is supposed to happen here.
+ template <typename T, int I> struct C;
+ template <typename T> struct C<T, T::value>;
+ // expected-error@-1 {{type of specialized non-type template argument depends on a template parameter of the partial specialization}}
+}
+
+namespace dr1330 { // dr1330: 4.0 c++11
+ // exception-specifications are parsed in a context where the class is complete.
+ struct A {
+ void f() throw(T) {} // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
+ struct T {};
+
+#if __cplusplus >= 201103L
+ void g() noexcept(&a == b) {}
+ static int a;
+ static constexpr int *b = &a;
+#endif
+ };
+
+ void (A::*af1)() throw(A::T) = &A::f; // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
+ void (A::*af2)() throw() = &A::f; // expected-error-re {{{{not superset|different exception spec}}}}
+
+#if __cplusplus >= 201103L
+ static_assert(noexcept(A().g()), "");
+#endif
+
+ // Likewise, they're instantiated separately from an enclosing class template.
+ template<typename U>
+ struct B {
+ void f() throw(T, typename U::type) {} // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
+ struct T {};
+
+#if __cplusplus >= 201103L
+ void g() noexcept(&a == b && U::value) {}
+ static int a;
+ static constexpr int *b = &a;
+#endif
+ };
+
+ B<int> bi; // ok
+
+ struct P {
+ typedef int type;
+ static const int value = true;
+ };
+
+ void (B<P>::*bpf1)() throw(B<P>::T, int) = &B<P>::f; // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
+#if __cplusplus < 201103L
+ // expected-error@-2 {{not superset}}
+ // FIXME: We only delay instantiation in C++11 onwards. In C++98, something
+ // weird happens: instantiation of B<P> fails because it references T before
+ // it's instantiated, but the diagnostic is suppressed in
+ // Sema::FindInstantiatedDecl because we've already hit an error. This is
+ // obviously a bad way to react to this situation; we should still producing
+ // the "T has not yet been instantiated" error here, rather than giving
+ // confusing errors later on.
+#endif
+ void (B<P>::*bpf2)() throw(int) = &B<P>::f; // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{not superset}}
+#else
+ // expected-warning@-4 {{not superset}}
+#endif
+ void (B<P>::*bpf3)() = &B<P>::f;
+ void (B<P>::*bpf4)() throw() = &B<P>::f;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{not superset}}
+#else
+ // expected-error@-4 {{different exception specifications}}
+#endif
+
+#if __cplusplus >= 201103L
+ static_assert(noexcept(B<P>().g()), "");
+ struct Q { static const int value = false; };
+ static_assert(!noexcept(B<Q>().g()), "");
+#endif
+
+ template<typename T> int f() throw(typename T::error) { return 0; } // expected-error 1-4{{prior to '::'}} expected-note 0-1{{instantiation of}}
+#if __cplusplus > 201402L
+ // expected-error@-2 0-1{{C++1z}} expected-note@-2 0-1{{noexcept}}
+#endif
+ // An exception-specification is needed even if the function is only used in
+ // an unevaluated operand.
+ int f1 = sizeof(f<int>()); // expected-note {{instantiation of}}
+#if __cplusplus >= 201103L
+ decltype(f<char>()) f2; // expected-note {{instantiation of}}
+ bool f3 = noexcept(f<float>()); // expected-note {{instantiation of}}
+#endif
+ template int f<short>(); // expected-note {{instantiation of}}
+
+ template<typename T> struct C {
+ C() throw(typename T::type); // expected-error 1-2{{prior to '::'}}
+#if __cplusplus > 201402L
+ // expected-error@-2 0-1{{C++1z}} expected-note@-2 0-1{{noexcept}}
+#endif
+ };
+ struct D : C<void> {}; // ok
+#if __cplusplus < 201103L
+ // expected-note@-2 {{instantiation of}}
+#endif
+ void f(D &d) { d = d; } // ok
+
+ // FIXME: In C++11 onwards, we should also note the declaration of 'e' as the
+ // line that triggers the use of E::E()'s exception specification.
+ struct E : C<int> {}; // expected-note {{in instantiation of}}
+ E e;
+}
+
namespace dr1346 { // dr1346: 3.5
auto a(1); // expected-error 0-1{{extension}}
auto b(1, 2); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}
diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp
index 9491f7da14760..9e724d9183460 100644
--- a/test/CXX/drs/dr14xx.cpp
+++ b/test/CXX/drs/dr14xx.cpp
@@ -342,4 +342,32 @@ namespace dr1490 { // dr1490: 3.7 c++11
char s[4]{"abc"}; // Ok
std::initializer_list<char>{"abc"}; // expected-error {{expected unqualified-id}}}
} // dr190
+
+namespace dr1495 { // dr1495: 4.0
+ // Deduction succeeds in both directions.
+ template<typename T, typename U> struct A {}; // expected-note {{template is declared here}}
+ template<typename T, typename U> struct A<U, T> {}; // expected-error {{class template partial specialization is not more specialized}}
+
+ // Primary template is more specialized.
+ template<typename, typename...> struct B {}; // expected-note {{template is declared here}}
+ template<typename ...Ts> struct B<Ts...> {}; // expected-error {{not more specialized}}
+
+ // Deduction fails in both directions.
+ template<int, typename, typename ...> struct C {}; // expected-note {{template is declared here}}
+ template<typename ...Ts> struct C<0, Ts...> {}; // expected-error {{not more specialized}}
+
+#if __cplusplus >= 201402L
+ // Deduction succeeds in both directions.
+ template<typename T, typename U> int a; // expected-note {{template is declared here}}
+ template<typename T, typename U> int a<U, T>; // expected-error {{variable template partial specialization is not more specialized}}
+
+ // Primary template is more specialized.
+ template<typename, typename...> int b; // expected-note {{template is declared here}}
+ template<typename ...Ts> int b<Ts...>; // expected-error {{not more specialized}}
+
+ // Deduction fails in both directions.
+ template<int, typename, typename ...> int c; // expected-note {{template is declared here}}
+ template<typename ...Ts> int c<0, Ts...>; // expected-error {{not more specialized}}
+#endif
+}
#endif
diff --git a/test/CXX/drs/dr158.cpp b/test/CXX/drs/dr158.cpp
new file mode 100644
index 0000000000000..33f837ca06270
--- /dev/null
+++ b/test/CXX/drs/dr158.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+
+// dr158: yes
+
+// CHECK-LABEL: define {{.*}} @_Z1f
+const int *f(const int * const *p, int **q) {
+ // CHECK: load i32**, {{.*}}, !tbaa ![[INTPTR_TBAA:[^,]*]]
+ const int *x = *p;
+ // CHECK: store i32* null, {{.*}}, !tbaa ![[INTPTR_TBAA]]
+ *q = 0;
+ return x;
+}
+
+struct A {};
+
+// CHECK-LABEL: define {{.*}} @_Z1g
+const int *(A::*const *g(const int *(A::* const **p)[3], int *(A::***q)[3]))[3] {
+ // CHECK: load i64**, {{.*}}, !tbaa ![[MEMPTR_TBAA:[^,]*]]
+ const int *(A::*const *x)[3] = *p;
+ // CHECK: store i64* null, {{.*}}, !tbaa ![[MEMPTR_TBAA]]
+ *q = 0;
+ return x;
+}
+
diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp
index 5f85a196fd6af..fb0d9334f6b6f 100644
--- a/test/CXX/drs/dr15xx.cpp
+++ b/test/CXX/drs/dr15xx.cpp
@@ -3,9 +3,223 @@
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-#if __cplusplus < 201103L
-// expected-no-diagnostics
+namespace dr1512 { // dr1512: 4.0
+ void f(char *p) {
+ if (p > 0) {} // expected-error {{ordered comparison between pointer and zero}}
+#if __cplusplus >= 201103L
+ if (p > nullptr) {} // expected-error {{invalid operands}}
#endif
+ }
+ bool g(int **x, const int **y) {
+ return x < y;
+ }
+
+ template<typename T> T val();
+
+ template<typename A, typename B, typename C> void composite_pointer_type_is_base() {
+ typedef __typeof(true ? val<A>() : val<B>()) type;
+ typedef C type;
+
+ typedef __typeof(val<A>() == val<B>()) cmp;
+ typedef __typeof(val<A>() != val<B>()) cmp;
+ typedef bool cmp;
+ }
+
+ template<typename A, typename B, typename C> void composite_pointer_type_is_ord() {
+ composite_pointer_type_is_base<A, B, C>();
+
+ typedef __typeof(val<A>() < val<B>()) cmp;
+ typedef __typeof(val<A>() <= val<B>()) cmp;
+ typedef __typeof(val<A>() > val<B>()) cmp;
+ typedef __typeof(val<A>() >= val<B>()) cmp;
+ typedef bool cmp;
+ }
+
+ template <typename A, typename B, typename C>
+ void composite_pointer_type_is_unord(int = 0) {
+ composite_pointer_type_is_base<A, B, C>();
+ }
+ template <typename A, typename B, typename C>
+ void composite_pointer_type_is_unord(__typeof(val<A>() < val<B>()) * = 0);
+ template <typename A, typename B, typename C>
+ void composite_pointer_type_is_unord(__typeof(val<A>() <= val<B>()) * = 0);
+ template <typename A, typename B, typename C>
+ void composite_pointer_type_is_unord(__typeof(val<A>() > val<B>()) * = 0);
+ template <typename A, typename B, typename C>
+ void composite_pointer_type_is_unord(__typeof(val<A>() >= val<B>()) * = 0);
+
+ // A call to this is ambiguous if a composite pointer type exists.
+ template<typename A, typename B>
+ void no_composite_pointer_type(__typeof((true ? val<A>() : val<B>()), void()) * = 0);
+ template<typename A, typename B> void no_composite_pointer_type(int = 0);
+
+ struct A {};
+ struct B : A {};
+ struct C {};
+
+ void test() {
+#if __cplusplus >= 201103L
+ using nullptr_t = decltype(nullptr);
+ composite_pointer_type_is_unord<nullptr_t, nullptr_t, nullptr_t>();
+ no_composite_pointer_type<nullptr_t, int>();
+
+ composite_pointer_type_is_unord<nullptr_t, const char**, const char**>();
+ composite_pointer_type_is_unord<const char**, nullptr_t, const char**>();
+#endif
+
+ composite_pointer_type_is_ord<const int *, volatile void *, const volatile void*>();
+ composite_pointer_type_is_ord<const void *, volatile int *, const volatile void*>();
+
+ composite_pointer_type_is_ord<const A*, volatile B*, const volatile A*>();
+ composite_pointer_type_is_ord<const B*, volatile A*, const volatile A*>();
+
+ composite_pointer_type_is_unord<const int *A::*, volatile int *B::*, const volatile int *const B::*>();
+ composite_pointer_type_is_unord<const int *B::*, volatile int *A::*, const volatile int *const B::*>();
+ no_composite_pointer_type<int (A::*)(), int (C::*)()>();
+ no_composite_pointer_type<const int (A::*)(), volatile int (C::*)()>();
+
+#if __cplusplus > 201402
+ composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>();
+ composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>();
+ composite_pointer_type_is_unord<int (A::*)() noexcept, int (A::*)(), int (A::*)()>();
+ composite_pointer_type_is_unord<int (A::*)(), int (A::*)() noexcept, int (A::*)()>();
+ // FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'.
+ composite_pointer_type_is_unord<int (B::*)(), int (A::*)() noexcept, int (B::*)()>();
+ composite_pointer_type_is_unord<int (A::*)() noexcept, int (B::*)(), int (B::*)()>();
+ composite_pointer_type_is_unord<int (B::*)() noexcept, int (A::*)(), int (B::*)()>();
+ composite_pointer_type_is_unord<int (A::*)(), int (B::*)() noexcept, int (B::*)()>();
+
+ // FIXME: It would be reasonable to permit these, with a common type of 'int (*const *)()'.
+ no_composite_pointer_type<int (**)() noexcept, int (**)()>();
+ no_composite_pointer_type<int (**)(), int (**)() noexcept>();
+
+ // FIXME: It would be reasonable to permit these, with a common type of 'int (A::*)()'.
+ no_composite_pointer_type<int (A::*)() const, int (A::*)()>();
+ no_composite_pointer_type<int (A::*)(), int (A::*)() const>();
+
+ // FIXME: It would be reasonable to permit these, with a common type of
+ // 'int (A::*)() &' and 'int (A::*)() &&', respectively.
+ no_composite_pointer_type<int (A::*)() &, int (A::*)()>();
+ no_composite_pointer_type<int (A::*)(), int (A::*)() &>();
+ no_composite_pointer_type<int (A::*)() &&, int (A::*)()>();
+ no_composite_pointer_type<int (A::*)(), int (A::*)() &&>();
+
+ no_composite_pointer_type<int (A::*)() &&, int (A::*)() &>();
+ no_composite_pointer_type<int (A::*)() &, int (A::*)() &&>();
+
+ no_composite_pointer_type<int (C::*)(), int (A::*)() noexcept>();
+ no_composite_pointer_type<int (A::*)() noexcept, int (C::*)()>();
+#endif
+ }
+
+ template<typename T> struct Wrap { operator T(); };
+ void test_overload() {
+#if __cplusplus >= 201103L
+ using nullptr_t = decltype(nullptr);
+ void(Wrap<nullptr_t>() == Wrap<nullptr_t>());
+ void(Wrap<nullptr_t>() != Wrap<nullptr_t>());
+ void(Wrap<nullptr_t>() < Wrap<nullptr_t>()); // expected-error {{invalid operands}}
+ void(Wrap<nullptr_t>() > Wrap<nullptr_t>()); // expected-error {{invalid operands}}
+ void(Wrap<nullptr_t>() <= Wrap<nullptr_t>()); // expected-error {{invalid operands}}
+ void(Wrap<nullptr_t>() >= Wrap<nullptr_t>()); // expected-error {{invalid operands}}
+
+ // The wording change fails to actually disallow this. This is valid
+ // via the builtin operator<(int*, int*) etc.
+ void(Wrap<nullptr_t>() == Wrap<int*>());
+ void(Wrap<nullptr_t>() != Wrap<int*>());
+ void(Wrap<nullptr_t>() < Wrap<int*>());
+ void(Wrap<nullptr_t>() > Wrap<int*>());
+ void(Wrap<nullptr_t>() <= Wrap<int*>());
+ void(Wrap<nullptr_t>() >= Wrap<int*>());
+#endif
+ }
+}
+
+namespace dr1518 { // dr1518: 4.0
+#if __cplusplus >= 201103L
+struct Z0 { // expected-note 0+ {{candidate}}
+ explicit Z0() = default; // expected-note 0+ {{here}}
+};
+struct Z { // expected-note 0+ {{candidate}}
+ explicit Z(); // expected-note 0+ {{here}}
+ explicit Z(int);
+ explicit Z(int, int); // expected-note 0+ {{here}}
+};
+template <class T> int Eat(T); // expected-note 0+ {{candidate}}
+Z0 a;
+Z0 b{};
+Z0 c = {}; // expected-error {{explicit in copy-initialization}}
+int i = Eat<Z0>({}); // expected-error {{no matching function for call to 'Eat'}}
+
+Z c2 = {}; // expected-error {{explicit in copy-initialization}}
+int i2 = Eat<Z>({}); // expected-error {{no matching function for call to 'Eat'}}
+Z a1 = 1; // expected-error {{no viable conversion}}
+Z a3 = Z(1);
+Z a2(1);
+Z *p = new Z(1);
+Z a4 = (Z)1;
+Z a5 = static_cast<Z>(1);
+Z a6 = {4, 3}; // expected-error {{explicit in copy-initialization}}
+
+struct UserProvidedBaseCtor { // expected-note 0+ {{candidate}}
+ UserProvidedBaseCtor() {}
+};
+struct DoesntInheritCtor : UserProvidedBaseCtor { // expected-note 0+ {{candidate}}
+ int x;
+};
+DoesntInheritCtor I{{}, 42};
+#if __cplusplus <= 201402L
+// expected-error@-2 {{no matching constructor}}
+#endif
+
+struct BaseCtor { BaseCtor() = default; }; // expected-note 0+ {{candidate}}
+struct InheritsCtor : BaseCtor { // expected-note 1+ {{candidate}}
+ using BaseCtor::BaseCtor; // expected-note 2 {{inherited here}}
+ int x;
+};
+InheritsCtor II = {{}, 42}; // expected-error {{no matching constructor}}
+
+namespace std_example {
+ struct A {
+ explicit A() = default; // expected-note 2{{declared here}}
+ };
+
+ struct B : A {
+ explicit B() = default; // expected-note 2{{declared here}}
+ };
+
+ struct C {
+ explicit C(); // expected-note 2{{declared here}}
+ };
+
+ struct D : A {
+ C c;
+ explicit D() = default; // expected-note 2{{declared here}}
+ };
+
+ template <typename T> void f() {
+ T t; // ok
+ T u{}; // ok
+ T v = {}; // expected-error 4{{explicit}}
+ }
+ template <typename T> void g() {
+ void x(T t); // expected-note 4{{parameter}}
+ x({}); // expected-error 4{{explicit}}
+ }
+
+ void test() {
+ f<A>(); // expected-note {{instantiation of}}
+ f<B>(); // expected-note {{instantiation of}}
+ f<C>(); // expected-note {{instantiation of}}
+ f<D>(); // expected-note {{instantiation of}}
+ g<A>(); // expected-note {{instantiation of}}
+ g<B>(); // expected-note {{instantiation of}}
+ g<C>(); // expected-note {{instantiation of}}
+ g<D>(); // expected-note {{instantiation of}}
+ }
+}
+#endif // __cplusplus >= 201103L
+}
namespace dr1550 { // dr1550: yes
int f(bool b, int n) {
diff --git a/test/CXX/drs/dr16xx.cpp b/test/CXX/drs/dr16xx.cpp
index 65467e35e4d68..02aa5f9909eb3 100644
--- a/test/CXX/drs/dr16xx.cpp
+++ b/test/CXX/drs/dr16xx.cpp
@@ -3,10 +3,6 @@
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-#if __cplusplus < 201103L
-// expected-no-diagnostics
-#endif
-
namespace dr1684 { // dr1684: 3.6
#if __cplusplus >= 201103L
struct NonLiteral { // expected-note {{because}}
@@ -44,6 +40,35 @@ namespace dr1631 { // dr1631: 3.7
#endif
}
+namespace dr1638 { // dr1638: yes
+#if __cplusplus >= 201103L
+ template<typename T> struct A {
+ enum class E; // expected-note {{previous}}
+ enum class F : T; // expected-note 2{{previous}}
+ };
+
+ template<> enum class A<int>::E;
+ template<> enum class A<int>::E {};
+ template<> enum class A<int>::F : int;
+ template<> enum class A<int>::F : int {};
+
+ template<> enum class A<short>::E : int;
+ template<> enum class A<short>::E : int {};
+
+ template<> enum class A<short>::F; // expected-error {{different underlying type}}
+ template<> enum class A<char>::E : char; // expected-error {{different underlying type}}
+ template<> enum class A<char>::F : int; // expected-error {{different underlying type}}
+
+ enum class A<unsigned>::E; // expected-error {{template specialization requires 'template<>'}} expected-error {{nested name specifier}}
+ template enum class A<unsigned>::E; // expected-error {{enumerations cannot be explicitly instantiated}}
+ enum class A<unsigned>::E *e; // expected-error {{must use 'enum' not 'enum class'}}
+
+ struct B {
+ friend enum class A<unsigned>::E; // expected-error {{must use 'enum' not 'enum class'}}
+ };
+#endif
+}
+
namespace dr1645 { // dr1645: 3.9
#if __cplusplus >= 201103L
struct A { // expected-note 2{{candidate}}
@@ -60,3 +85,19 @@ namespace dr1645 { // dr1645: 3.9
constexpr B b(0, 0); // expected-error {{ambiguous}}
#endif
}
+
+namespace dr1653 { // dr1653: 4.0 c++17
+ void f(bool b) {
+ ++b;
+ b++;
+#if __cplusplus <= 201402L
+ // expected-warning@-3 {{deprecated}} expected-warning@-2 {{deprecated}}
+#else
+ // expected-error@-5 {{incrementing expression of type bool}} expected-error@-4 {{incrementing expression of type bool}}
+#endif
+ --b; // expected-error {{cannot decrement expression of type bool}}
+ b--; // expected-error {{cannot decrement expression of type bool}}
+ b += 1; // ok
+ b -= 1; // ok
+ }
+}
diff --git a/test/CXX/drs/dr18xx.cpp b/test/CXX/drs/dr18xx.cpp
index bc72b67d1e0b7..436bccc8e42e3 100644
--- a/test/CXX/drs/dr18xx.cpp
+++ b/test/CXX/drs/dr18xx.cpp
@@ -7,11 +7,11 @@
// expected-no-diagnostics
#endif
-void dr1891() { // dr1891: 3.6
+void dr1891() { // dr1891: 4.0
#if __cplusplus >= 201103L
int n;
- auto a = []{}; // expected-note 2{{candidate}}
- auto b = [=]{ return n; }; // expected-note 2{{candidate}}
+ auto a = []{}; // expected-note 2{{candidate}} expected-note 2{{here}}
+ auto b = [=]{ return n; }; // expected-note 2{{candidate}} expected-note 2{{here}}
typedef decltype(a) A;
typedef decltype(b) B;
@@ -20,5 +20,10 @@ void dr1891() { // dr1891: 3.6
A x; // expected-error {{no matching constructor}}
B y; // expected-error {{no matching constructor}}
+
+ a = a; // expected-error {{copy assignment operator is implicitly deleted}}
+ a = static_cast<A&&>(a); // expected-error {{copy assignment operator is implicitly deleted}}
+ b = b; // expected-error {{copy assignment operator is implicitly deleted}}
+ b = static_cast<B&&>(b); // expected-error {{copy assignment operator is implicitly deleted}}
#endif
}
diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index 8d368a5a54e85..9521f0a8b7841 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/test/CXX/drs/dr1xx.cpp
@@ -35,7 +35,7 @@ namespace dr102 { // dr102: yes
}
// dr103: na
-// dr104 FIXME: add codegen test
+// dr104: na lib
// dr105: na
namespace dr106 { // dr106: sup 540
@@ -202,7 +202,7 @@ namespace dr116 { // dr116: yes
}
// dr117: na
-// dr118 FIXME: add codegen test
+// dr118 is in its own file.
// dr119: na
// dr120: na
@@ -235,13 +235,11 @@ namespace dr125 {
friend dr125_A (::dr125_B::dr125_C)(); // ok
friend dr125_A::dr125_B::dr125_C(); // expected-error {{did you mean the constructor name 'dr125_B'?}}
// expected-error@-1 {{missing exception specification}}
-#if __cplusplus >= 201103L
- // expected-error@-3 {{follows constexpr declaration}} expected-note@-10 {{here}}
-#endif
};
}
namespace dr126 { // dr126: no
+#if __cplusplus <= 201402L
struct C {};
struct D : C {};
struct E : private C { friend class A; friend class B; };
@@ -314,12 +312,15 @@ namespace dr126 { // dr126: no
virtual void y() throw(int*); // ok
virtual void z() throw(long); // expected-error {{more lax}}
};
+#else
+ void f() throw(int); // expected-error {{ISO C++1z does not allow}} expected-note {{use 'noexcept}}
+#endif
}
namespace dr127 { // dr127: yes
__extension__ typedef __decltype(sizeof(0)) size_t;
template<typename T> struct A {
- A() throw(int);
+ A() { throw 0; }
void *operator new(size_t, const char * = 0);
void operator delete(void *, const char *) { T::error; } // expected-error 2{{no members}}
void operator delete(void *) { T::error; }
@@ -579,11 +580,18 @@ namespace dr151 { // dr151: yes
namespace dr152 { // dr152: yes
struct A {
- A(); // expected-note {{not viable}}
+ A(); // expected-note 0-2{{not viable}}
explicit A(const A&);
};
- A a1 = A(); // expected-error {{no matching constructor}}
+ A a1 = A();
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{no matching constructor}}
+#endif
A a2((A()));
+
+ A &f();
+ A a3 = f(); // expected-error {{no matching constructor}}
+ A a4(f());
}
// dr153: na
@@ -600,7 +608,7 @@ namespace dr155 { // dr155: dup 632
struct S { int n; } s = { { 1 } }; // expected-warning {{braces around scalar initializer}}
}
-// dr158 FIXME write codegen test
+// dr158 is in its own file.
namespace dr159 { // dr159: 3.5
namespace X { void f(); }
@@ -826,11 +834,20 @@ namespace dr176 { // dr176: yes
namespace dr177 { // dr177: yes
struct B {};
struct A {
- A(A &); // expected-note {{not viable: expects an l-value}}
- A(const B &);
+ A(A &); // expected-note 0-1{{not viable: expects an l-value}}
+ A(const B &); // expected-note 0-1{{not viable: no known conversion from 'dr177::A' to}}
};
B b;
- A a = b; // expected-error {{no viable constructor copying variable}}
+ A a = b;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{no viable constructor copying variable}}
+#endif
+
+ struct C { C(C&); }; // expected-note {{not viable: no known conversion from 'dr177::D' to 'dr177::C &'}}
+ struct D : C {};
+ struct E { operator D(); };
+ E e;
+ C c = e; // expected-error {{no viable constructor copying variable of type 'dr177::D'}}
}
namespace dr178 { // dr178: yes
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index 25c853590ae66..a9f0c8fcc9995 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -620,7 +620,7 @@ namespace dr254 { // dr254: yes
template<typename T> struct A {
typedef typename T::type type; // ok even if this is a typedef-name, because
// it's not an elaborated-type-specifier
- typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}}
+ typedef struct T::type foo; // expected-error {{typedef 'type' cannot be referenced with a struct specifier}}
};
struct B { struct type {}; };
struct C { typedef struct {} type; }; // expected-note {{here}}
@@ -679,17 +679,13 @@ namespace dr258 { // dr258: yes
} f; // expected-error {{abstract}}
}
-namespace dr259 { // dr259: yes c++11
+namespace dr259 { // dr259: 4.0
template<typename T> struct A {};
template struct A<int>; // expected-note {{previous}}
template struct A<int>; // expected-error {{duplicate explicit instantiation}}
- // FIXME: We only apply this DR in C++11 mode.
- template<> struct A<float>;
- template struct A<float>;
-#if __cplusplus < 201103L
- // expected-error@-2 {{extension}} expected-note@-3 {{here}}
-#endif
+ template<> struct A<float>; // expected-note {{previous}}
+ template struct A<float>; // expected-warning {{has no effect}}
template struct A<char>; // expected-note {{here}}
template<> struct A<char>; // expected-error {{explicit specialization of 'dr259::A<char>' after instantiation}}
@@ -702,11 +698,8 @@ namespace dr259 { // dr259: yes c++11
template<typename T> struct B; // expected-note {{here}}
template struct B<int>; // expected-error {{undefined}}
- template<> struct B<float>;
- template struct B<float>;
-#if __cplusplus < 201103L
- // expected-error@-2 {{extension}} expected-note@-3 {{here}}
-#endif
+ template<> struct B<float>; // expected-note {{previous}}
+ template struct B<float>; // expected-warning {{has no effect}}
}
// FIXME: When dr260 is resolved, also add tests for DR507.
@@ -990,12 +983,32 @@ namespace dr289 { // dr289: yes
namespace dr294 { // dr294: no
void f() throw(int);
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
int main() {
- (void)static_cast<void (*)() throw()>(f); // FIXME: ill-formed
- (void)static_cast<void (*)() throw(int)>(f); // FIXME: ill-formed
+ (void)static_cast<void (*)() throw()>(f); // FIXME: ill-formed in C++14 and before
+#if __cplusplus > 201402L
+ // FIXME: expected-error@-2 {{not allowed}}
+ //
+ // Irony: the above is valid in C++17 and beyond, but that's exactly when
+ // we reject it. In C++14 and before, this is ill-formed because an
+ // exception-specification is not permitted in a type-id. In C++17, this is
+ // valid because it's the inverse of a standard conversion sequence
+ // containing a function pointer conversion. (Well, it's actually not valid
+ // yet, as a static_cast is not permitted to reverse a function pointer
+ // conversion, but that is being changed by core issue).
+#endif
+ (void)static_cast<void (*)() throw(int)>(f); // FIXME: ill-formed in C++14 and before
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
- void (*p)() throw() = f; // expected-error {{not superset}}
+ void (*p)() throw() = f; // expected-error-re {{{{not superset|different exception specification}}}}
void (*q)() throw(int) = f;
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
}
}
@@ -1035,8 +1048,8 @@ namespace dr298 { // dr298: yes
C::type i3;
struct A a;
- struct B b; // expected-error {{refers to a typedef}}
- struct C c; // expected-error {{refers to a typedef}}
+ struct B b; // expected-error {{typedef 'B' cannot be referenced with a struct specifier}}
+ struct C c; // expected-error {{typedef 'C' cannot be referenced with a struct specifier}}
B::B() {} // expected-error {{requires a type specifier}}
B::A() {} // ok
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp
index b1c21f8631dd1..6046c4afefd55 100644
--- a/test/CXX/drs/dr4xx.cpp
+++ b/test/CXX/drs/dr4xx.cpp
@@ -90,7 +90,7 @@ namespace dr407 { // dr407: 3.8
struct S *p;
{
typedef struct S S; // expected-note {{here}}
- struct S *p; // expected-error {{refers to a typedef}}
+ struct S *p; // expected-error {{typedef 'S' cannot be referenced with a struct specifier}}
}
}
struct S {};
@@ -327,7 +327,7 @@ namespace dr420 { // dr420: yes
namespace dr421 { // dr421: yes
struct X { X(); int n; int &r; };
- int *p = &X().n; // expected-error {{taking the address of a temporary}}
+ int *p = &X().n; // expected-error-re {{{{taking the address of a temporary|cannot take the address of an rvalue}}}}
int *q = &X().r;
}
@@ -508,9 +508,18 @@ namespace dr437 { // dr437: sup 1308
template<typename U> struct T : U {};
struct S {
void f() throw(S);
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
void g() throw(T<S>);
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
struct U;
void h() throw(U);
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
struct U {};
};
}
@@ -553,12 +562,21 @@ namespace dr446 { // dr446: yes
void(b ? a : a);
b ? A() : a; // expected-error {{deleted}}
b ? a : A(); // expected-error {{deleted}}
- b ? A() : A(); // expected-error {{deleted}}
+ b ? A() : A();
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{deleted}}
+#endif
void(b ? a : c);
b ? a : C(); // expected-error {{deleted}}
- b ? c : A(); // expected-error {{deleted}}
- b ? A() : C(); // expected-error {{deleted}}
+ b ? c : A();
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{deleted}}
+#endif
+ b ? A() : C();
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{deleted}}
+#endif
}
}
@@ -874,10 +892,12 @@ namespace dr479 { // dr479: yes
void f() {
throw S();
// expected-error@-1 {{temporary of type 'dr479::S' has private destructor}}
- // expected-error@-2 {{calling a private constructor}}
- // expected-error@-3 {{exception object of type 'dr479::S' has private destructor}}
+ // expected-error@-2 {{exception object of type 'dr479::S' has private destructor}}
#if __cplusplus < 201103L
- // expected-error@-5 {{C++98 requires an accessible copy constructor}}
+ // expected-error@-4 {{C++98 requires an accessible copy constructor}}
+#endif
+#if __cplusplus <= 201402L
+ // expected-error@-7 {{calling a private constructor}} (copy ctor)
#endif
}
void g() {
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
index e0bab57e5254b..f065128cd4bd8 100644
--- a/test/CXX/drs/dr5xx.cpp
+++ b/test/CXX/drs/dr5xx.cpp
@@ -8,6 +8,12 @@
// with -verify.
__extension__ typedef __SIZE_TYPE__ size_t;
void *operator new(size_t); // expected-error 0-1{{missing exception spec}} expected-note{{candidate}}
+#if __cplusplus > 201402L
+namespace std {
+ enum class align_val_t : size_t {};
+}
+void *operator new(size_t, std::align_val_t); // expected-note{{candidate}}
+#endif
namespace dr500 { // dr500: dup 372
class D;
@@ -857,14 +863,13 @@ namespace dr580 { // dr580: partial
// dr582: na
-namespace dr583 { // dr583: no
+namespace dr583 { // dr583: 4.0
// see n3624
int *p;
- // FIXME: These are all ill-formed.
- bool b1 = p < 0;
- bool b2 = p > 0;
- bool b3 = p <= 0;
- bool b4 = p >= 0;
+ bool b1 = p < 0; // expected-error {{ordered comparison between pointer and zero}}
+ bool b2 = p > 0; // expected-error {{ordered comparison between pointer and zero}}
+ bool b3 = p <= 0; // expected-error {{ordered comparison between pointer and zero}}
+ bool b4 = p >= 0; // expected-error {{ordered comparison between pointer and zero}}
}
// dr584: na
@@ -948,6 +953,9 @@ namespace dr591 { // dr591: no
namespace dr595 { // dr595: dup 1330
template<class T> struct X {
void f() throw(T) {}
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++1z does not allow}} expected-note@-2 {{use 'noexcept}}
+#endif
};
struct S {
X<S> xs;
diff --git a/test/CXX/drs/dr6xx.cpp b/test/CXX/drs/dr6xx.cpp
index 1d37a6d3e80c8..9dfcc7d6b4646 100644
--- a/test/CXX/drs/dr6xx.cpp
+++ b/test/CXX/drs/dr6xx.cpp
@@ -142,15 +142,21 @@ namespace dr615 { // dr615: yes
static int n = f();
}
-namespace dr616 { // dr616: no
+namespace dr616 { // dr616: 4.0
#if __cplusplus >= 201103L
struct S { int n; } s;
- // FIXME: These should all be 'int &&'
- using T = decltype(S().n);
- using T = decltype(static_cast<S&&>(s).n);
- using T = decltype(S().*&S::n); // expected-note 2{{previous}}
- using T = decltype(static_cast<S&&>(s).*&S::n); // expected-error {{different type}}
- using T = int&&; // expected-error {{different type}}
+ S f();
+ using T = decltype((S().n));
+ using T = decltype((static_cast<S&&>(s).n));
+ using T = decltype((f().n));
+ using T = decltype(S().*&S::n);
+ using T = decltype(static_cast<S&&>(s).*&S::n);
+ using T = decltype(f().*&S::n);
+ using T = int&&;
+
+ using U = decltype(S().n);
+ using U = decltype(static_cast<S&&>(s).n);
+ using U = int;
#endif
}
@@ -347,3 +353,66 @@ namespace dr639 { // dr639: yes
void((i = 0) + (i = 0)); // expected-warning {{unsequenced}}
}
}
+
+namespace dr692 { // dr692: no
+ namespace temp_func_order_example2 {
+ template <typename T, typename U> struct A {};
+ template <typename T, typename U> void f(U, A<U, T> *p = 0); // expected-note {{candidate}}
+ template <typename U> int &f(U, A<U, U> *p = 0); // expected-note {{candidate}}
+ template <typename T> void g(T, T = T());
+ template <typename T, typename... U> void g(T, U...); // expected-error 0-1{{C++11}}
+ void h() {
+ int &r = f<int>(42, (A<int, int> *)0);
+ f<int>(42); // expected-error {{ambiguous}}
+ // FIXME: We should reject this due to ambiguity between the pack and the
+ // default argument. Only parameters with arguments are considered during
+ // partial ordering of function templates.
+ g(42);
+ }
+ }
+
+ namespace temp_func_order_example3 {
+ template <typename T, typename... U> void f(T, U...); // expected-error 0-1{{C++11}}
+ template <typename T> void f(T);
+ template <typename T, typename... U> int &g(T *, U...); // expected-error 0-1{{C++11}}
+ template <typename T> void g(T);
+ void h(int i) {
+ // This is made ambiguous by dr692, but made valid again by dr1395.
+ f(&i);
+ int &r = g(&i);
+ }
+ }
+
+ namespace temp_deduct_partial_example {
+ template <typename... Args> char &f(Args... args); // expected-error 0-1{{C++11}}
+ template <typename T1, typename... Args> short &f(T1 a1, Args... args); // expected-error 0-1{{C++11}}
+ template <typename T1, typename T2> int &f(T1 a1, T2 a2);
+ void g() {
+ char &a = f();
+ short &b = f(1, 2, 3);
+ int &c = f(1, 2);
+ }
+ }
+
+ namespace temp_deduct_type_example1 {
+ template <class T1, class ...Z> class S; // expected-error 0-1{{C++11}}
+ template <class T1, class ...Z> class S<T1, const Z&...>; // expected-error 0-1{{C++11}}
+ template <class T1, class T2> class S<T1, const T2&> {};
+ S<int, const int&> s;
+
+ // FIXME: This should select the first partial specialization. Deduction of
+ // the second from the first should succeed, because we should ignore the
+ // trailing pack in A with no corresponding P.
+ template<class T, class... U> struct A; // expected-error 0-1{{C++11}}
+ template<class T1, class T2, class... U> struct A<T1,T2*,U...>; // expected-note {{matches}} expected-error 0-1{{C++11}}
+ template<class T1, class T2> struct A<T1,T2> {}; // expected-note {{matches}}
+ template struct A<int, int*>; // expected-error {{ambiguous}}
+ }
+
+ namespace temp_deduct_type_example3 {
+ // FIXME: This should select the first template, as in the case above.
+ template<class T, class... U> void f(T*, U...){} // expected-note {{candidate}} expected-error 0-1{{C++11}}
+ template<class T> void f(T){} // expected-note {{candidate}}
+ template void f(int*); // expected-error {{ambiguous}}
+ }
+}
diff --git a/test/CXX/except/except.spec/p2-places-1z.cpp b/test/CXX/except/except.spec/p2-places-1z.cpp
new file mode 100644
index 0000000000000..619ea33b5349b
--- /dev/null
+++ b/test/CXX/except/except.spec/p2-places-1z.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++1z -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// In C++1z, we can put an exception-specification on any function declarator; the
+// corresponding paragraph from C++14 and before was deleted.
+// expected-no-diagnostics
+
+void f() noexcept;
+void (*fp)() noexcept;
+void (**fpp)() noexcept;
+void g(void (**pfa)() noexcept);
+void (**h())() noexcept;
+
+template<typename T> struct A {};
+template<void() noexcept> struct B {};
+A<void() noexcept> a;
+B<f> b;
+auto *p = new decltype(f)**;
diff --git a/test/CXX/except/except.spec/p2-places.cpp b/test/CXX/except/except.spec/p2-places.cpp
index 67647fb043a98..ea842af898459 100644
--- a/test/CXX/except/except.spec/p2-places.cpp
+++ b/test/CXX/except/except.spec/p2-places.cpp
@@ -37,6 +37,8 @@ namespace dyn {
// Pointer to function returning pointer to pointer to function with spec
void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}}
+ // FIXME: Missing a lot of negative tests, primarily type-ids in various places
+ // We fail to diagnose all of those.
}
namespace noex {
diff --git a/test/CXX/except/except.spec/p5-pointers.cpp b/test/CXX/except/except.spec/p5-pointers.cpp
index fe4a264587f5a..dedc5bd376f92 100644
--- a/test/CXX/except/except.spec/p5-pointers.cpp
+++ b/test/CXX/except/except.spec/p5-pointers.cpp
@@ -41,25 +41,25 @@ void fnptrs()
{
// Assignment and initialization of function pointers.
void (*t1)() throw() = &s1; // valid
- t1 = &s2; // expected-error {{not superset}} expected-error {{incompatible type}}
- t1 = &s3; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t1 = &s2; // expected-error {{not superset}}
+ t1 = &s3; // expected-error {{not superset}}
void (&t2)() throw() = s2; // expected-error {{not superset}}
void (*t3)() throw(int) = &s2; // valid
void (*t4)() throw(A) = &s1; // valid
t4 = &s3; // valid
t4 = &s4; // valid
- t4 = &s5; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t4 = &s5; // expected-error {{not superset}}
void (*t5)() = &s1; // valid
t5 = &s2; // valid
t5 = &s6; // valid
t5 = &s7; // valid
- t1 = t3; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t1 = t3; // expected-error {{not superset}}
t3 = t1; // valid
void (*t6)() throw(B1);
- t6 = t4; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t6 = t4; // expected-error {{not superset}}
t4 = t6; // valid
t5 = t1; // valid
- t1 = t5; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t1 = t5; // expected-error {{not superset}}
// return types and arguments must match exactly, no inheritance allowed
void (*(*t7)())() throw(B1) = &s8; // valid
diff --git a/test/CXX/expr/expr.cond/p4.cpp b/test/CXX/expr/expr.cond/p4.cpp
new file mode 100644
index 0000000000000..4d0cf3538cf05
--- /dev/null
+++ b/test/CXX/expr/expr.cond/p4.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++98 -verify %s
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+// expected-no-diagnostics
+
+struct A { A(); A(int); };
+void f() {
+ const A a;
+ true ? a : 0;
+}
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index fd15960647ca0..6d46bf5d77dd9 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -33,11 +33,11 @@ struct NonConstexpr3 {
int m : NonConstexpr2().n; // expected-error {{constant expression}} expected-note {{undefined constructor 'NonConstexpr2'}}
};
struct NonConstexpr4 {
- NonConstexpr4(); // expected-note {{declared here}}
+ NonConstexpr4();
int n;
};
struct NonConstexpr5 {
- int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4' cannot be used in a constant expression}}
+ int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-literal type 'NonConstexpr4' cannot be used in a constant expression}}
};
// - an invocation of an undefined constexpr function or an undefined
@@ -321,7 +321,7 @@ namespace LValueToRValue {
// temporary object whose lifetime has not ended, initialized with a
// constant expression;
constexpr volatile S f() { return S(); }
- static_assert(f().i, ""); // ok! there's no lvalue-to-rvalue conversion here!
+ static_assert(f().i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
static_assert(((volatile const S&&)(S)0).i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
}
@@ -461,14 +461,14 @@ namespace UnspecifiedRelations {
constexpr bool u2 = p > q; // expected-error {{constant expression}}
constexpr bool u3 = p <= q; // expected-error {{constant expression}}
constexpr bool u4 = p >= q; // expected-error {{constant expression}}
- constexpr bool u5 = p < 0; // expected-error {{constant expression}}
- constexpr bool u6 = p <= 0; // expected-error {{constant expression}}
- constexpr bool u7 = p > 0; // expected-error {{constant expression}}
- constexpr bool u8 = p >= 0; // expected-error {{constant expression}}
- constexpr bool u9 = 0 < q; // expected-error {{constant expression}}
- constexpr bool u10 = 0 <= q; // expected-error {{constant expression}}
- constexpr bool u11 = 0 > q; // expected-error {{constant expression}}
- constexpr bool u12 = 0 >= q; // expected-error {{constant expression}}
+ constexpr bool u5 = p < (int*)0; // expected-error {{constant expression}}
+ constexpr bool u6 = p <= (int*)0; // expected-error {{constant expression}}
+ constexpr bool u7 = p > (int*)0; // expected-error {{constant expression}}
+ constexpr bool u8 = p >= (int*)0; // expected-error {{constant expression}}
+ constexpr bool u9 = (int*)0 < q; // expected-error {{constant expression}}
+ constexpr bool u10 = (int*)0 <= q; // expected-error {{constant expression}}
+ constexpr bool u11 = (int*)0 > q; // expected-error {{constant expression}}
+ constexpr bool u12 = (int*)0 >= q; // expected-error {{constant expression}}
void f(), g();
constexpr void (*pf)() = &f, (*pg)() = &g;
@@ -522,7 +522,7 @@ namespace UnspecifiedRelations {
constexpr void *null = 0;
constexpr void *pv = (void*)&s.a;
constexpr void *qv = (void*)&s.b;
- constexpr bool v1 = null < 0;
+ constexpr bool v1 = null < (int*)0;
constexpr bool v2 = null < pv; // expected-error {{constant expression}}
constexpr bool v3 = null == pv; // ok
constexpr bool v4 = qv == pv; // ok
diff --git a/test/CXX/expr/expr.const/p3-0x.cpp b/test/CXX/expr/expr.const/p3-0x.cpp
index d9d84853ebae9..731e0c312fa13 100644
--- a/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/test/CXX/expr/expr.const/p3-0x.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s
// A converted constant expression of type T is a core constant expression,
int nonconst = 8; // expected-note 3 {{here}}
@@ -40,10 +41,10 @@ const E e10 = E10;
template<E> struct T {};
T<e10> s10;
-// integral promotions, and
+// integral promotions,
enum class EE { EE32 = ' ', EE65 = 'A', EE1 = (short)1, EE5 = E5 };
-// integral conversions other than narrowing conversions
+// integral conversions other than narrowing conversions,
int b(unsigned n) {
switch (n) {
case E6:
@@ -74,12 +75,22 @@ using Int = A<-3>; // expected-error {{template argument evaluates to -3, which
// Note, conversions from integral or unscoped enumeration types to bool are
// integral conversions as well as boolean conversions.
+// FIXME: Per core issue 1407, this is not correct.
template<typename T, T v> struct Val { static constexpr T value = v; };
static_assert(Val<bool, E1>::value == 1, ""); // ok
static_assert(Val<bool, '\0'>::value == 0, ""); // ok
static_assert(Val<bool, U'\1'>::value == 1, ""); // ok
static_assert(Val<bool, E5>::value == 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}}
+// function pointer conversions [C++17]
+void noexcept_false() noexcept(false);
+void noexcept_true() noexcept(true);
+Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept;
+Val<decltype(&noexcept_true), &noexcept_false> add_noexcept;
+#if __cplusplus > 201402L
+// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'void (*)() noexcept'}}
+#endif
+
// (no other conversions are permitted)
using Int = A<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}}
enum B : bool {
diff --git a/test/CXX/expr/expr.post/expr.static.cast/p3-p4-0x.cpp b/test/CXX/expr/expr.post/expr.static.cast/p3-p4-0x.cpp
new file mode 100644
index 0000000000000..8701a00d5cf01
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.static.cast/p3-p4-0x.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+
+// p3
+// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to
+// cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1" (8.5.3).
+// p4
+// Otherwise, an expression e can be explicitly converted to a type T using a
+// static_cast of the form static_cast<T>(e) if the declaration T t(e); is
+// well-formed, for some invented temporary variable t (8.5). [...]
+struct A { };
+struct B : A { };
+
+struct C { explicit operator A&&(); };
+struct D { operator B(); };
+
+template<typename T> T& lvalue();
+template<typename T> T&& xvalue();
+template <typename T> T prvalue();
+
+void test(A &a, B &b) {
+ A &&ar0 = static_cast<A&&>(prvalue<A>());
+ A &&ar1 = static_cast<A&&>(prvalue<B>());
+ A &&ar2 = static_cast<A&&>(lvalue<C>());
+ A &&ar3 = static_cast<A&&>(xvalue<C>());
+ A &&ar4 = static_cast<A&&>(prvalue<C>());
+ A &&ar5 = static_cast<A&&>(lvalue<D>());
+ A &&ar6 = static_cast<A&&>(xvalue<D>());
+ A &&ar7 = static_cast<A&&>(prvalue<D>());
+
+ A &&ar8 = static_cast<A&&>(prvalue<const A>()); // expected-error {{binding value of type 'const A' to reference to type 'A' drops 'const' qualifier}}
+ A &&ar9 = static_cast<A&&>(lvalue<const A>()); // expected-error {{cannot cast from lvalue of type 'const A'}}
+ A &&ar10 = static_cast<A&&>(xvalue<const A>()); // expected-error {{cannot cast from rvalue of type 'const A'}}
+
+ const A &&ar11 = static_cast<const A&&>(prvalue<A>());
+ const A &&ar12 = static_cast<const A&&>(prvalue<B>());
+ const A &&ar13 = static_cast<const A&&>(lvalue<C>());
+ const A &&ar14 = static_cast<const A&&>(xvalue<C>());
+ const A &&ar15 = static_cast<const A&&>(prvalue<C>());
+ const A &&ar16 = static_cast<const A&&>(lvalue<D>());
+
+ const A &&ar17 = static_cast<const A&&>(prvalue<A const volatile>()); // expected-error {{binding value of type 'const volatile A' to reference to type 'const A' drops 'volatile' qualifier}}
+}
diff --git a/test/CXX/expr/expr.post/expr.static.cast/p7.cpp b/test/CXX/expr/expr.post/expr.static.cast/p7.cpp
new file mode 100644
index 0000000000000..fd8e478b5193b
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.static.cast/p7.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions
+
+void (*p)() noexcept;
+void (*q)();
+
+void f() {
+ // FIXME: This seems like a bad rule.
+ p = static_cast<decltype(p)>(q); // expected-error {{not allowed}}
+ q = static_cast<decltype(q)>(p);
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
index 40360e40694c1..1dbcbf498031d 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -7,7 +7,7 @@ struct MoveOnly {
template<typename T> T &&move(T&);
void test_special_member_functions(MoveOnly mo, int i) {
- auto lambda1 = [i]() { }; // expected-note {{lambda expression begins here}} expected-note 2{{candidate}}
+ auto lambda1 = [i]() { }; // expected-note 2{{lambda expression begins here}} expected-note 2{{candidate}}
// Default constructor
decltype(lambda1) lambda2; // expected-error{{no matching constructor}}
@@ -16,7 +16,7 @@ void test_special_member_functions(MoveOnly mo, int i) {
lambda1 = lambda1; // expected-error{{copy assignment operator is implicitly deleted}}
// Move assignment operator
- lambda1 = move(lambda1);
+ lambda1 = move(lambda1); // expected-error{{copy assignment operator is implicitly deleted}}
// Copy constructor
decltype(lambda1) lambda3 = lambda1;
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
index 8b43cefa92c06..90a3aec50cb38 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -verify
void test_conversion() {
int (*fp1)(int) = [](int x) { return x + 1; };
@@ -9,6 +10,15 @@ void test_conversion() {
volatile const auto lambda2 = [](int x) { }; // expected-note{{but method is not marked volatile}}
void (*fp4)(int) = lambda2; // expected-error{{no viable conversion}}
+
+ void (*fp5)(int) noexcept = [](int x) { };
+#if __cplusplus > 201402L
+ // expected-error@-2 {{no viable}} expected-note@-2 {{candidate}}
+ void (*fp5a)(int) noexcept = [](auto x) { };
+ // expected-error@-1 {{no viable}} expected-note@-1 {{candidate}}
+ void (*fp5b)(int) noexcept = [](auto x) noexcept { };
+#endif
+ void (*fp6)(int) noexcept = [](int x) noexcept { };
}
void test_no_conversion() {
diff --git a/test/CXX/expr/expr.unary/expr.delete/p10.cpp b/test/CXX/expr/expr.unary/expr.delete/p10.cpp
new file mode 100644
index 0000000000000..aad2747dd32f2
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.delete/p10.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+using size_t = decltype(sizeof(0));
+namespace std { enum class align_val_t : size_t {}; }
+
+// Aligned version is preferred over unaligned version,
+// unsized version is preferred over sized version.
+template<unsigned Align>
+struct alignas(Align) A {
+ void operator delete(void*);
+ void operator delete(void*, std::align_val_t) = delete; // expected-note {{here}}
+
+ void operator delete(void*, size_t) = delete;
+ void operator delete(void*, size_t, std::align_val_t) = delete;
+};
+void f(A<__STDCPP_DEFAULT_NEW_ALIGNMENT__> *p) { delete p; }
+void f(A<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2> *p) { delete p; } // expected-error {{deleted}}
+
+template<unsigned Align>
+struct alignas(Align) B {
+ void operator delete(void*, size_t);
+ void operator delete(void*, size_t, std::align_val_t) = delete; // expected-note {{here}}
+};
+void f(B<__STDCPP_DEFAULT_NEW_ALIGNMENT__> *p) { delete p; }
+void f(B<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2> *p) { delete p; } // expected-error {{deleted}}
diff --git a/test/CXX/expr/expr.unary/expr.new/p14.cpp b/test/CXX/expr/expr.unary/expr.new/p14.cpp
new file mode 100644
index 0000000000000..6537cdcfeafa0
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p14.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -std=c++1z -fsized-deallocation -fexceptions %s -verify
+
+using size_t = decltype(sizeof(0));
+namespace std { enum class align_val_t : size_t {}; }
+
+struct Arg {} arg;
+
+// If the type is aligned, first try with an alignment argument and then
+// without. If not, never consider supplying an alignment.
+
+template<unsigned Align, typename ...Ts>
+struct alignas(Align) Unaligned {
+ void *operator new(size_t, Ts...) = delete; // expected-note 4{{deleted}}
+};
+auto *ua = new Unaligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__>; // expected-error {{deleted}}
+auto *ub = new Unaligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2>; // expected-error {{deleted}}
+auto *uap = new (arg) Unaligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__, Arg>; // expected-error {{deleted}}
+auto *ubp = new (arg) Unaligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2, Arg>; // expected-error {{deleted}}
+
+template<unsigned Align, typename ...Ts>
+struct alignas(Align) Aligned {
+ void *operator new(size_t, std::align_val_t, Ts...) = delete; // expected-note 2{{deleted}} expected-note 2{{not viable}}
+};
+auto *aa = new Aligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__>; // expected-error {{no matching}}
+auto *ab = new Aligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2>; // expected-error {{deleted}}
+auto *aap = new (arg) Aligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__, Arg>; // expected-error {{no matching}}
+auto *abp = new (arg) Aligned<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2, Arg>; // expected-error {{deleted}}
+
+// If both are available, we prefer the aligned version for an overaligned
+// type, and only use the unaligned version for a non-overaligned type.
+
+template<unsigned Align, typename ...Ts>
+struct alignas(Align) Both1 {
+ void *operator new(size_t, Ts...); // expected-note 2{{not viable}}
+ void *operator new(size_t, std::align_val_t, Ts...) = delete; // expected-note 2{{deleted}}
+};
+template<unsigned Align, typename ...Ts>
+struct alignas(Align) Both2 {
+ void *operator new(size_t, Ts...) = delete; // expected-note 2{{deleted}}
+ void *operator new(size_t, std::align_val_t, Ts...); // expected-note 2{{not viable}}
+};
+auto *b1a = new Both1<__STDCPP_DEFAULT_NEW_ALIGNMENT__>;
+auto *b1b = new Both1<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2>; // expected-error {{deleted}}
+auto *b2a = new Both2<__STDCPP_DEFAULT_NEW_ALIGNMENT__>; // expected-error {{deleted}}
+auto *b2b = new Both2<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2>;
+auto *b1ap = new (arg) Both1<__STDCPP_DEFAULT_NEW_ALIGNMENT__, Arg>;
+auto *b1bp = new (arg) Both1<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2, Arg>; // expected-error {{deleted}}
+auto *b2ap = new (arg) Both2<__STDCPP_DEFAULT_NEW_ALIGNMENT__, Arg>; // expected-error {{deleted}}
+auto *b2bp = new (arg) Both2<__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2, Arg>;
+
+// Note that the aligned form can select a function with a parameter different
+// from std::align_val_t.
+
+struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) WeirdAlignedAlloc1 {
+ void *operator new(size_t, ...) = delete; // expected-note 2{{deleted}}
+};
+auto *waa1 = new WeirdAlignedAlloc1; // expected-error {{deleted}}
+auto *waa1p = new (arg) WeirdAlignedAlloc1; // expected-error {{deleted}}
+
+struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) WeirdAlignedAlloc2 {
+ template<typename ...T>
+ void *operator new(size_t, T...) {
+ using U = void(T...); // expected-note 2{{previous}}
+ using U = void; // expected-error {{different types ('void' vs 'void (std::align_val_t)')}} \
+ expected-error {{different types ('void' vs 'void (std::align_val_t, Arg)')}}
+ }
+};
+auto *waa2 = new WeirdAlignedAlloc2; // expected-note {{instantiation of}}
+auto *waa2p = new (arg) WeirdAlignedAlloc2; // expected-note {{instantiation of}}
diff --git a/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp b/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
index eca1ec7901999..13676a8a07cec 100644
--- a/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
+++ b/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
@@ -1,6 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fexceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -fexceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -fexceptions %s
typedef __SIZE_TYPE__ size_t;
+namespace std { enum class align_val_t : size_t {}; }
+
struct S {
// Placement allocation function:
static void* operator new(size_t, size_t);
@@ -9,5 +13,56 @@ struct S {
};
void testS() {
- S* p = new (0) S; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+ S* p = new (0) S; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+}
+
+struct T {
+ // Placement allocation function:
+ static void* operator new(size_t, size_t);
+ // Usual (non-placement) deallocation function:
+ static void operator delete(void*);
+ // Placement deallocation function:
+ static void operator delete(void*, size_t);
+};
+
+void testT() {
+ T* p = new (0) T; // ok
+}
+
+#if __cplusplus > 201402L
+struct U {
+ // Placement allocation function:
+ static void* operator new(size_t, size_t, std::align_val_t);
+ // Placement deallocation function:
+ static void operator delete(void*, size_t, std::align_val_t); // expected-note{{declared here}}
+};
+
+void testU() {
+ U* p = new (0, std::align_val_t(0)) U; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+}
+
+struct V {
+ // Placement allocation function:
+ static void* operator new(size_t, size_t, std::align_val_t);
+ // Usual (non-placement) deallocation function:
+ static void operator delete(void*, std::align_val_t);
+ // Placement deallocation function:
+ static void operator delete(void*, size_t, std::align_val_t);
+};
+
+void testV() {
+ V* p = new (0, std::align_val_t(0)) V;
+}
+
+struct W {
+ // Placement allocation function:
+ static void* operator new(size_t, size_t, std::align_val_t);
+ // Usual (non-placement) deallocation functions:
+ static void operator delete(void*);
+ static void operator delete(void*, size_t, std::align_val_t); // expected-note {{declared here}}
+};
+
+void testW() {
+ W* p = new (0, std::align_val_t(0)) W; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
}
+#endif
diff --git a/test/CXX/expr/p13.cpp b/test/CXX/expr/p13.cpp
new file mode 100644
index 0000000000000..0f22ce0b7cebc
--- /dev/null
+++ b/test/CXX/expr/p13.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s -fexceptions -fcxx-exceptions -Wno-dynamic-exception-spec
+
+struct X {};
+struct Y : X {};
+
+using A = void (*)() noexcept;
+using B = void (*)();
+using C = void (X::*)() noexcept;
+using D = void (X::*)();
+using E = void (Y::*)() noexcept;
+using F = void (Y::*)();
+
+void f(A a, B b, C c, D d, E e, F f, bool k) {
+ a = k ? a : b; // expected-error {{different exception specifications}}
+ b = k ? a : b;
+
+ c = k ? c : d; // expected-error {{different exception specifications}}
+ d = k ? c : d;
+
+ e = k ? c : f; // expected-error {{different exception specifications}}
+ e = k ? d : e; // expected-error {{different exception specifications}}
+ f = k ? c : f;
+ f = k ? d : e;
+
+ const A ak = a;
+ const B bk = b;
+ const A &ak2 = k ? ak : ak;
+ const A &ak3 = k ? ak : bk; // expected-error {{could not bind}}
+ const B &bk3 = k ? ak : bk;
+}
+
+namespace dynamic_exception_spec {
+ // Prior to P0012, we had:
+ // "[...] the target entity shall allow at least the exceptions allowed
+ // by the source value in the assignment or initialization"
+ //
+ // There's really only one way we can coherently apply this to conditional
+ // expressions: this must hold no matter which branch was taken.
+ using X = void (*)() throw(int);
+ using Y = void (*)() throw(float);
+ using Z = void (*)() throw(int, float);
+ void g(X x, Y y, Z z, bool k) {
+ x = k ? X() : Y(); // expected-warning {{not superset}}
+ y = k ? X() : Y(); // expected-warning {{not superset}}
+ z = k ? X() : Y();
+
+ x = k ? x : y; // expected-warning {{not superset}}
+ y = k ? x : y; // expected-warning {{not superset}}
+ z = k ? x : y;
+ }
+}
diff --git a/test/CXX/over/over.built/p15.cpp b/test/CXX/over/over.built/p15.cpp
new file mode 100644
index 0000000000000..64ed3e7b83ded
--- /dev/null
+++ b/test/CXX/over/over.built/p15.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+struct A { operator decltype(nullptr)(); };
+struct B { operator const int *(); };
+void f(A a, B b, volatile int *pi) {
+ (void)(a == a);
+ (void)(a != a);
+ (void)(a < a); // expected-error {{invalid operands}}
+ (void)(a > a); // expected-error {{invalid operands}}
+ (void)(a <= a); // expected-error {{invalid operands}}
+ (void)(a >= a); // expected-error {{invalid operands}}
+
+ (void)(a == b);
+ (void)(a != b);
+ // FIXME: These cases were intended to be made ill-formed by N3624, but it
+ // fails to actually achieve this goal.
+ (void)(a < b);
+ (void)(a > b);
+ (void)(a <= b);
+ (void)(a >= b);
+
+ (void)(b == a);
+ (void)(b != a);
+ // FIXME: These cases were intended to be made ill-formed by N3624, but it
+ // fails to actually achieve this goal.
+ (void)(b < a);
+ (void)(b > a);
+ (void)(b <= a);
+ (void)(b >= a);
+
+ (void)(a == pi);
+ (void)(a != pi);
+ // FIXME: These cases were intended to be made ill-formed by N3624, but it
+ // fails to actually achieve this goal.
+ (void)(a < pi);
+ (void)(a > pi);
+ (void)(a <= pi);
+ (void)(a >= pi);
+
+ (void)(pi == a);
+ (void)(pi != a);
+ // FIXME: These cases were intended to be made ill-formed by N3624, but it
+ // fails to actually achieve this goal.
+ (void)(pi < a);
+ (void)(pi > a);
+ (void)(pi <= a);
+ (void)(pi >= a);
+
+ (void)(b == pi);
+ (void)(b != pi);
+ (void)(b < pi);
+ (void)(b > pi);
+ (void)(b <= pi);
+ (void)(b >= pi);
+
+ (void)(pi == b);
+ (void)(pi != b);
+ (void)(pi < b);
+ (void)(pi > b);
+ (void)(pi <= b);
+ (void)(pi >= b);
+
+ (void)(b == b);
+ (void)(b != b);
+ (void)(b < b);
+ (void)(b > b);
+ (void)(b <= b);
+ (void)(b >= b);
+
+ (void)(pi == pi);
+ (void)(pi != pi);
+ (void)(pi < pi);
+ (void)(pi > pi);
+ (void)(pi <= pi);
+ (void)(pi >= pi);
+}
+
+// FIXME: This is wrong: the type T = 'const volatile int * const * const *'
+// would work here, and there exists a builtin candidate for that type.
+struct C { operator const int ***(); };
+void g(C c, volatile int ***p) {
+ (void)(c < p); // expected-error {{invalid operands}}
+}
diff --git a/test/CXX/over/over.built/p16.cpp b/test/CXX/over/over.built/p16.cpp
new file mode 100644
index 0000000000000..139e864475244
--- /dev/null
+++ b/test/CXX/over/over.built/p16.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+struct A { operator decltype(nullptr)(); };
+struct B { operator int A::*(); };
+void f(A a, B b, int A::*pi) {
+ (void)(a == a);
+ (void)(a != a);
+ (void)(a < a); // expected-error {{invalid operands}}
+ (void)(a > a); // expected-error {{invalid operands}}
+ (void)(a <= a); // expected-error {{invalid operands}}
+ (void)(a >= a); // expected-error {{invalid operands}}
+
+ (void)(a == b);
+ (void)(a != b);
+ (void)(a < b); // expected-error {{invalid operands}}
+ (void)(a > b); // expected-error {{invalid operands}}
+ (void)(a <= b); // expected-error {{invalid operands}}
+ (void)(a >= b); // expected-error {{invalid operands}}
+
+ (void)(b == a);
+ (void)(b != a);
+ (void)(b < a); // expected-error {{invalid operands}}
+ (void)(b > a); // expected-error {{invalid operands}}
+ (void)(b <= a); // expected-error {{invalid operands}}
+ (void)(b >= a); // expected-error {{invalid operands}}
+
+ (void)(a == pi);
+ (void)(a != pi);
+ (void)(a < pi); // expected-error {{invalid operands}}
+ (void)(a > pi); // expected-error {{invalid operands}}
+ (void)(a <= pi); // expected-error {{invalid operands}}
+ (void)(a >= pi); // expected-error {{invalid operands}}
+
+ (void)(pi == a);
+ (void)(pi != a);
+ (void)(pi < a); // expected-error {{invalid operands}}
+ (void)(pi > a); // expected-error {{invalid operands}}
+ (void)(pi <= a); // expected-error {{invalid operands}}
+ (void)(pi >= a); // expected-error {{invalid operands}}
+
+ (void)(b == pi);
+ (void)(b != pi);
+ (void)(b < pi); // expected-error {{invalid operands}}
+ (void)(b > pi); // expected-error {{invalid operands}}
+ (void)(b <= pi); // expected-error {{invalid operands}}
+ (void)(b >= pi); // expected-error {{invalid operands}}
+
+ (void)(pi == b);
+ (void)(pi != b);
+ (void)(pi < b); // expected-error {{invalid operands}}
+ (void)(pi > b); // expected-error {{invalid operands}}
+ (void)(pi <= b); // expected-error {{invalid operands}}
+ (void)(pi >= b); // expected-error {{invalid operands}}
+
+ (void)(b == b);
+ (void)(b != b);
+ (void)(b < b); // expected-error {{invalid operands}}
+ (void)(b > b); // expected-error {{invalid operands}}
+ (void)(b <= b); // expected-error {{invalid operands}}
+ (void)(b >= b); // expected-error {{invalid operands}}
+
+ (void)(pi == pi);
+ (void)(pi != pi);
+ (void)(pi < pi); // expected-error {{invalid operands}}
+ (void)(pi > pi); // expected-error {{invalid operands}}
+ (void)(pi <= pi); // expected-error {{invalid operands}}
+ (void)(pi >= pi); // expected-error {{invalid operands}}
+}
+
+// FIXME: This is wrong: type T = 'const volatile int * const A::* const B::*'
+// would work here, and there exists a builtin candidate for that type.
+struct C { operator const int *A::*B::*(); };
+void g(C c, volatile int *A::*B::*p) {
+ (void)(c == p); // expected-error {{invalid operands}}
+}
diff --git a/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.scs/p3.cpp b/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.scs/p3.cpp
new file mode 100644
index 0000000000000..df2fc2cd2e82b
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.scs/p3.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+void f(void() noexcept); // expected-note {{no known conversion from 'void ()' to 'void (*)() noexcept'}}
+void f(void()) = delete; // expected-note {{explicitly deleted}}
+
+void g();
+void h() noexcept;
+
+void test() {
+ f(g); // expected-error {{call to deleted}}
+ f(h);
+}
diff --git a/test/CXX/over/over.oper/over.literal/p6.cpp b/test/CXX/over/over.oper/over.literal/p6.cpp
index 6bfb8560d6889..9ecf9ccccb14c 100644
--- a/test/CXX/over/over.oper/over.literal/p6.cpp
+++ b/test/CXX/over/over.oper/over.literal/p6.cpp
@@ -1,9 +1,11 @@
// RUN: %clang_cc1 -std=c++11 %s -verify
+// expected-note@+1 {{extern "C" language linkage specification begins here}}
extern "C" void operator "" _a(const char *); // expected-error {{must have C++ linkage}}
extern "C" template<char...> void operator "" _b(); // expected-error {{must have C++ linkage}}
+// expected-note@-1 {{extern "C" language linkage specification begins here}}
-extern "C" {
+extern "C" { // expected-note 4 {{extern "C" language linkage specification begins here}}
void operator "" _c(const char *); // expected-error {{must have C++ linkage}}
template<char...> void operator "" _d(); // expected-error {{must have C++ linkage}}
namespace N {
diff --git a/test/CXX/over/over.over/p1.cpp b/test/CXX/over/over.over/p1.cpp
index 10c60da013cbc..e31a2c5067562 100644
--- a/test/CXX/over/over.over/p1.cpp
+++ b/test/CXX/over/over.over/p1.cpp
@@ -1,7 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -DNOEXCEPT= -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -DNOEXCEPT= -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -DNOEXCEPT=noexcept -verify %s
-template<typename T> T f0(T);
-int f0(int);
+template<typename T> T f0(T) NOEXCEPT;
+int f0(int) NOEXCEPT;
// -- an object or reference being initialized
struct S {
@@ -92,3 +94,18 @@ Y1<f0> y1;
Y1<&f0> y1a;
Y2<f0> y2;
Y3<f0> y3;
+
+#if __cplusplus > 201402L
+namespace MixedNoexcept {
+ inline namespace A {
+ void f() noexcept; // expected-note {{candidate}}
+ }
+ inline namespace B {
+ void f(); // expected-note {{candidate}}
+ }
+ void (*p)() noexcept = &f; // ok
+ void (*q)() = &f; // expected-error {{ambiguous}}
+}
+#else
+// expected-no-diagnostics
+#endif
diff --git a/test/CXX/special/class.copy/implicit-move-def.cpp b/test/CXX/special/class.copy/implicit-move-def.cpp
index f344b0cc6a0f3..7a6a1ee984e92 100644
--- a/test/CXX/special/class.copy/implicit-move-def.cpp
+++ b/test/CXX/special/class.copy/implicit-move-def.cpp
@@ -110,8 +110,8 @@ void move_VirtualWithEmptyBase(VirtualWithEmptyBase &x, VirtualWithEmptyBase &y)
// CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_
// CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_
// array loop
-// CHECK-CTOR: br i1
// CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_
+// CHECK-CTOR: br i1
// CHECK-CTOR: define linkonce_odr {{.*}} @_ZN1GC2EOS_
// CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_
diff --git a/test/CXX/special/class.copy/p20.cpp b/test/CXX/special/class.copy/p20.cpp
index 8dfb7ca8a068d..4f17879ecfb70 100644
--- a/test/CXX/special/class.copy/p20.cpp
+++ b/test/CXX/special/class.copy/p20.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
struct ConstCopy {
ConstCopy();
diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp
index 2d7eba490bc8e..f6a64260e0df5 100644
--- a/test/CXX/special/class.dtor/p3-0x.cpp
+++ b/test/CXX/special/class.dtor/p3-0x.cpp
@@ -176,4 +176,4 @@ struct TVC : VX
template <typename T>
TVC<T>::~TVC() {}
-// CHECK: attributes [[ATTRGRP]] = { nounwind{{.*}} }
+// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} }
diff --git a/test/CXX/special/class.dtor/p5-0x.cpp b/test/CXX/special/class.dtor/p5-0x.cpp
index e32279ef125bb..595784f0d5f9d 100644
--- a/test/CXX/special/class.dtor/p5-0x.cpp
+++ b/test/CXX/special/class.dtor/p5-0x.cpp
@@ -90,7 +90,7 @@ class D1 {
public:
virtual ~D1() = default; // expected-note {{here}}
} d1; // ok
-struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} \
+struct D2 : D1 { // expected-note 2{{virtual destructor requires an unambiguous, accessible 'operator delete'}} \
// expected-error {{deleted function '~D2' cannot override a non-deleted}}
// implicitly-virtual destructor
} d2; // expected-error {{deleted function}}
diff --git a/test/CXX/special/class.dtor/p9.cpp b/test/CXX/special/class.dtor/p9.cpp
index 42a4236a4a079..e812491fbb4b3 100644
--- a/test/CXX/special/class.dtor/p9.cpp
+++ b/test/CXX/special/class.dtor/p9.cpp
@@ -1,7 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
-// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++11 %s
-typedef typeof(sizeof(int)) size_t;
+typedef __typeof(sizeof(int)) size_t;
// PR7803
namespace test0 {
@@ -29,13 +31,13 @@ namespace test0 {
namespace test1 {
class A {
public:
- static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}}
+ static void operator delete(void *p) {};
virtual ~A();
};
class B : protected A {
public:
- static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}}
+ static void operator delete(void *, size_t) {};
~B();
};
@@ -47,7 +49,20 @@ namespace test1 {
~C();
};
- C::~C() {} // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
+ // We assume that the intent is to treat C::operator delete(void*, size_t) as
+ // /not/ being a usual deallocation function, as it would be if it were
+ // declared with in C directly.
+ C::~C() {}
+
+ struct D {
+ void operator delete(void*); // expected-note {{member 'operator delete' declared here}}
+ void operator delete(void*, ...); // expected-note {{member 'operator delete' declared here}}
+ virtual ~D();
+ };
+ // FIXME: The standard doesn't say this is ill-formed, but presumably either
+ // it should be or the variadic operator delete should not be a usual
+ // deallocation function.
+ D::~D() {} // expected-error {{multiple suitable 'operator delete' functions in 'D'}}
}
// ...at the point of definition of a virtual destructor...
@@ -63,6 +78,7 @@ namespace test2 {
};
B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}}
+#if __cplusplus < 201103L
struct CBase { virtual ~CBase(); };
struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}}
static void operator delete(void*, const int &); // expected-note {{declared here}}
@@ -70,6 +86,15 @@ namespace test2 {
void test() {
C c; // expected-note {{first required here}}
}
+#else
+ struct CBase { virtual ~CBase(); }; // expected-note {{overridden virtual function is here}}
+ struct C : CBase { // expected-error {{deleted function '~C' cannot override a non-deleted function}} expected-note 2{{requires an unambiguous, accessible 'operator delete'}}
+ static void operator delete(void*, const int &);
+ };
+ void test() {
+ C c; // expected-error {{attempt to use a deleted function}}
+ }
+#endif
}
// PR7346
diff --git a/test/CXX/special/class.init/class.inhctor.init/p1.cpp b/test/CXX/special/class.init/class.inhctor.init/p1.cpp
index e07d879df8f1c..1f4362740b00e 100644
--- a/test/CXX/special/class.init/class.inhctor.init/p1.cpp
+++ b/test/CXX/special/class.init/class.inhctor.init/p1.cpp
@@ -87,6 +87,13 @@ namespace vbase {
D d2(0, 0); // expected-error {{deleted}}
}
+namespace vbase_of_vbase {
+ struct V { V(int); };
+ struct W : virtual V { using V::V; };
+ struct X : virtual W, virtual V { using W::W; };
+ X x(0);
+}
+
namespace constexpr_init_order {
struct Param;
struct A {
diff --git a/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp b/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
index d6a2169a5baf9..c33bf0eba231b 100644
--- a/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
+++ b/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
@@ -46,6 +46,11 @@ namespace ccce {
if constexpr (N) {} // expected-error {{cannot be narrowed}}
}
template void g<5>(); // expected-note {{instantiation of}}
+ void h() {
+ if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}
+ constexpr void *p = nullptr;
+ if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}}
+ }
}
namespace generic_lambda {
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 249563e7d9bf1..5341290a1446e 100644
--- a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -1,3 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
// RUN: %clang_cc1 -fsyntax-only -verify %s
// C++0x [temp.arg.nontype] p5:
@@ -45,15 +49,23 @@ namespace pointer_to_object_parameters {
operator int() const;
};
- template<X const *Ptr> struct A2; // expected-note{{template parameter is declared here}}
+ template<X const *Ptr> struct A2; // expected-note 0-1{{template parameter is declared here}}
- X *X_ptr;
+ X *X_ptr; // expected-note 0-1{{declared here}}
X an_X;
X array_of_Xs[10];
- A2<X_ptr> *a12; // expected-error{{must have its address taken}}
+ A2<X_ptr> *a12;
+#if __cplusplus < 201103L
+ // expected-error@-2 {{must have its address taken}}
+#else
+ // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-constexpr variable}}
+#endif
A2<array_of_Xs> *a13;
A2<&an_X> *a13_2;
- A2<(&an_X)> *a13_3; // expected-warning{{address non-type template argument cannot be surrounded by parentheses}}
+ A2<(&an_X)> *a13_3;
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{address non-type template argument cannot be surrounded by parentheses}}
+#endif
// PR6244
struct X1 {} X1v;
@@ -62,12 +74,24 @@ namespace pointer_to_object_parameters {
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 *bar; // expected-note 0-1{{declared here}}
+ template <int *> struct zed {}; // expected-note 0-2{{template parameter is declared here}}
+ void g(zed<bar>*);
+#if __cplusplus < 201103L
+ // expected-error@-2 {{must have its address taken}}
+#else
+ // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-constexpr variable}}
+#endif
- int baz;
- void g2(zed<baz>*); // expected-error{{must have its address taken}}
+ int baz; // expected-note 0-1{{declared here}}
+ void g2(zed<baz>*);
+#if __cplusplus < 201103L
+ // expected-error@-2 {{must have its address taken}}
+#elif __cplusplus <= 201402L
+ // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-const variable}}
+#else
+ // expected-error@-6 {{not implicitly convertible to 'int *'}}
+#endif
void g3(zed<&baz>*); // okay
}
@@ -78,9 +102,9 @@ namespace pointer_to_object_parameters {
// 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 <int& N> struct S0 { }; // expected-note 0-3{{template parameter is declared here}}
+ template <const int& N> struct S1 { }; // expected-note 0-2{{template parameter is declared here}}
+ template <volatile int& N> struct S2 { }; // expected-note 0-2{{template parameter is declared here}}
template <const volatile int& N> struct S3 { };
int i;
extern const int ci;
@@ -88,19 +112,19 @@ namespace reference_parameters {
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 'const int' ignores qualifiers}}
- S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'volatile int' ignores qualifiers}}
- S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const volatile int' ignores qualifiers}}
+ S0<ci> s0c; // expected-error{{type 'const int'}}
+ S0<vi> s0v; // expected-error{{type 'volatile int'}}
+ S0<cvi> s0cv; // expected-error{{type 'const volatile int'}}
S1<i> s1;
S1<ci> s1c;
- S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'volatile int' ignores qualifiers}}
- S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'const volatile int' ignores qualifiers}}
+ S1<vi> s1v; // expected-error{{type 'volatile int'}}
+ S1<cvi> s1cv; // expected-error{{type 'const volatile int'}}
S2<i> s2;
- S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const int' ignores qualifiers}}
+ S2<ci> s2c; // expected-error{{type 'const int'}}
S2<vi> s2v;
- S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const volatile int' ignores qualifiers}}
+ S2<cvi> s2cv; // expected-error{{type 'const volatile int'}}
S3<i> s3;
S3<ci> s3c;
@@ -125,9 +149,12 @@ namespace reference_parameters {
}
namespace PR6749 {
- template <int& i> struct foo {}; // expected-note{{template parameter is declared here}}
+ template <int& i> struct foo {}; // expected-note 0-1{{template parameter is declared here}}
int x, &y = x;
- foo<y> f; // expected-error{{is not an object}}
+ foo<y> f;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{is not an object}}
+#endif
}
}
@@ -138,16 +165,21 @@ namespace reference_parameters {
// 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}}
+ template<int (*)(int)> struct X0 { }; // expected-note 0-3{{template parameter is declared here}}
int f(int);
int f(float);
int g(float);
- int (*funcptr)(int);
+ int (*funcptr)(int); // expected-note 0-1{{declared here}}
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}}
+ void x0c(X0<g>); // expected-error-re{{type 'int (float)' {{.*}}convert{{.*}} 'int (*)(int)'}}
+ void x0d(X0<&g>); // expected-error-re{{type 'int (*)(float)' {{.*}}convert{{.*}} 'int (*)(int)'}}
+ void x0e(X0<funcptr>);
+#if __cplusplus < 201103L
+ // expected-error@-2 {{must have its address taken}}
+#else
+ // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-constexpr variable}}
+#endif
}
// -- For a non-type template-parameter of type reference to function, no
@@ -155,16 +187,23 @@ namespace pointer_to_function {
// 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}}
+ template<int (&)(int)> struct X0 { }; // expected-note 0-4{{template parameter is declared here}}
int f(int);
int f(float);
int g(float);
int (*funcptr)(int);
void x0a(X0<f>);
+#if __cplusplus <= 201402L
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)'}}
+#else
+ void x0b(X0<&f>); // expected-error{{value of type '<overloaded function type>' is not implicitly convertible to 'int (&)(int)'}}
+ void x0c(X0<g>); // expected-error{{value of type 'int (float)' is not implicitly convertible to 'int (&)(int)'}}
+ void x0d(X0<&g>); // expected-error{{value of type 'int (*)(float)' is not implicitly convertible to 'int (&)(int)'}}
+ void x0e(X0<funcptr>); // expected-error{{value of type 'int (*)(int)' is not implicitly convertible to 'int (&)(int)'}}
+#endif
}
// -- 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
@@ -181,10 +220,10 @@ namespace pointer_to_member_function {
float h(float);
};
- template<int (Y::*)(int)> struct X0 {}; // expected-note{{template parameter is declared here}}
+ template<int (Y::*)(int)> struct X0 {}; // expected-note 0-1{{template parameter is declared here}}
X0<&Y::f> x0a;
X0<&Y::g> x0b;
- X0<&Y::h> x0c; // expected-error-re{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
+ X0<&Y::h> x0c; // expected-error-re{{type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' {{.*}} convert{{.*}} 'int (pointer_to_member_function::Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
}
// -- For a non-type template-parameter of type pointer to data member,
@@ -195,9 +234,14 @@ 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}}
+ template<int Y::*> struct X0 {}; // expected-note 0-1{{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::*'}}
+ X0<&Y::x> x0b;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{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::*'}}
+#else
+ // expected-error@-4 {{conversion from 'int pointer_to_member_data::X::*' to 'int pointer_to_member_data::Y::*' is not allowed in a converted constant expression}}
+#endif
// Test qualification conversions
template<const int Y::*> struct X1 {};
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
index aa1e2d443fddb..52fbd94574229 100644
--- a/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
@@ -2,7 +2,10 @@
template<int ...Values> struct X1;
-template<int ...Values>
-struct X1<0, Values+1 ...>; // expected-error{{non-type template argument depends on a template parameter of the partial specialization}}
-
+template<int ...Values> // expected-note {{non-deducible}}
+struct X1<0, Values+1 ...>; // expected-error{{contains a template parameter that cannot be deduced}}
+template<typename T, int ...Values> struct X2; // expected-note {{here}}
+template<int ...Values> struct X2<X1<Values...>, Values+1 ...> {}; // ok (DR1315)
+X2<X1<1, 2, 3>, 2, 3, 4> x2; // ok
+X2<X1<1, 2, 3>, 2, 3, 4, 5> x3; // expected-error {{undefined template}}
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
index 2651f9942091a..388a80ee765c8 100644
--- a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
@@ -21,15 +21,16 @@ template<template<typename> class...X> int v4<X...>;
template<typename Outer> struct X {
template<typename Inner> static int y;
- template<typename Inner> static int y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'Inner'}}
+ // FIXME: It would be preferable to only diagnose this once.
+ template<typename Inner> static int y<Outer>; // expected-error 3{{cannot be deduced}} expected-note 3{{'Inner'}}
template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}}
+
+ template<typename, int> static int z;
+ template<Outer N> static int z<int, N>; // expected-error {{not implicitly convertible}}
};
-template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'Inner'}}
+template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-error {{cannot be deduced}} expected-note {{'Inner'}}
template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // expected-error {{does not specialize}}
+template<> template<typename Inner> int X<int>::y<Inner>; // expected-error {{does not specialize}} expected-note {{instantiation of}}
-// FIXME: Merging this with the above class causes an assertion failure when
-// instantiating one of the bogus partial specializations.
-template<typename Outer> struct Y {
- template<typename Inner> static int y;
-};
-template<> template<typename Inner> int Y<int>::y<Inner>; // expected-error {{does not specialize}}
+X<int> xi;
+X<int*> xf; // expected-note {{instantiation of}}
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
index 215f48d9d8e60..332357bb36a82 100644
--- a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
@@ -28,4 +28,4 @@ X2& get_X2() {
return X0<X2>::value; // expected-note{{instantiation}}
}
-template<typename T> T x; // expected-warning{{variable templates are a C++14 extension}}
+template<typename T> T x; // expected-warning 0-1{{variable templates are a C++14 extension}}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 640d03d4c96f0..f1f3f7016242c 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -174,7 +174,7 @@ namespace test7 {
// This shouldn't crash.
template <class T> class D {
- friend class A; // expected-error {{elaborated type refers to a template}}
+ friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}}
};
template class D<int>;
}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
index a466be0a61de9..a990c82564aa4 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
@@ -108,10 +108,10 @@ namespace PR9021b {
namespace PartialSpecialization {
template<typename T, typename U, typename V = U>
- struct X0; // expected-note{{template is declared here}}
+ struct X0; // expected-note 2{{template is declared here}}
template<typename ...Ts>
- struct X0<Ts...> {
+ struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}}
};
X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
index 9fd3df59d103e..f7103a33cc72d 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
@@ -32,8 +32,11 @@ namespace PR6707 {
static const unsigned char ten = 10;
template<typename T, T Value, typename U>
void f2(X<T, Value>, X<U, Value>);
+ // expected-note@-1 {{candidate template ignored: deduced values of conflicting types for parameter 'Value' (10 of type 'int' vs. 10 of type 'char')}}
+ // expected-note@-2 {{candidate template ignored: deduced values of conflicting types for parameter 'Value' (10 of type 'char' vs. 10 of type 'int')}}
void g2() {
- f2(X<int, 10>(), X<char, ten>());
+ f2(X<int, 10>(), X<char, ten>()); // expected-error {{no matching}}
+ f2(X<char, 10>(), X<int, ten>()); // expected-error {{no matching}}
}
}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp
index 132d61814227a..e7b665a341371 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
namespace PR8598 {
template<class T> struct identity { typedef T type; };
@@ -19,3 +19,38 @@ namespace PR12132 {
fun(&A::x);
}
}
+
+#if __cplusplus > 201402L
+namespace noexcept_conversion {
+ template<typename R> void foo(R());
+ template<typename R> void bar(R()) = delete;
+ template<typename R> void bar(R() noexcept) {}
+ void f() throw() {
+ foo(&f);
+ bar(&f);
+ }
+ // There is no corresponding rule for references.
+ // We consider this to be a defect, and allow deduction to succeed in this
+ // case. FIXME: Check this should be accepted once the DR is resolved.
+ template<typename R> void baz(R(&)());
+ void g() {
+ baz(f);
+ }
+
+ // But there is one for member pointers.
+ template<typename R, typename C, typename ...A> void quux(R (C::*)(A...));
+ struct Q { void f(int, char) noexcept { quux(&Q::f); } };
+
+ void g1() noexcept;
+ void g2();
+ template <class T> int h(T *, T *); // expected-note {{deduced conflicting types for parameter 'T' ('void () noexcept' vs. 'void ()')}}
+ int x = h(g1, g2); // expected-error {{no matching function}}
+
+ // FIXME: It seems like a defect that B is not deducible here.
+ template<bool B> int i(void () noexcept(B)); // expected-note 2{{couldn't infer template argument 'B'}}
+ int i1 = i(g1); // expected-error {{no matching function}}
+ int i2 = i(g2); // expected-error {{no matching function}}
+}
+#else
+// expected-no-diagnostics
+#endif
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
index 4dca820c1929c..b45ed96d14456 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only %s -verify
struct AnyT {
template<typename T>
@@ -11,34 +11,54 @@ void test_cvqual_ref(AnyT any) {
struct AnyThreeLevelPtr {
template<typename T>
- operator T***() const
- {
- T x = 0;
- // FIXME: looks like we get this wrong, too!
- // x = 0; // will fail if T is deduced to a const type
- // (EDG and GCC get this wrong)
- return 0;
+ operator T***() const {
+ T x = 0; // expected-note 2{{declared const here}}
+ x = 0; // expected-error 2{{const-qualified type}}
+ T ***p;
+ return p;
}
};
struct X { };
void test_deduce_with_qual(AnyThreeLevelPtr a3) {
- int * const * const * const ip = a3;
+ int * const * const * const ip1 = a3;
+ // FIXME: This is wrong; we are supposed to deduce 'T = int' here.
+ const int * const * const * const ip2 = a3; // expected-note {{instantiation of}}
+ // This one is correct, though.
+ const double * * * ip3 = a3; // expected-note {{instantiation of}}
}
struct AnyPtrMem {
template<typename Class, typename T>
operator T Class::*() const
{
- T x = 0;
- // FIXME: looks like we get this wrong, too!
- // x = 0; // will fail if T is deduced to a const type.
- // (EDG and GCC get this wrong)
+ // This is correct: we don't need a qualification conversion here, so we
+ // deduce 'T = const float'.
+ T x = 0; // expected-note {{declared const here}}
+ x = 0; // expected-error {{const-qualified type}}
return 0;
}
};
void test_deduce_ptrmem_with_qual(AnyPtrMem apm) {
- const float X::* pm = apm;
+ const float X::* pm = apm; // expected-note {{instantiation of}}
+}
+
+struct TwoLevelPtrMem {
+ template<typename Class1, typename Class2, typename T>
+ operator T Class1::*Class2::*() const
+ {
+ T x = 0; // expected-note 2{{declared const here}}
+ x = 0; // expected-error 2{{const-qualified type}}
+ return 0;
+ }
+};
+
+void test_deduce_two_level_ptrmem_with_qual(TwoLevelPtrMem apm) {
+ // FIXME: This is wrong: we should deduce T = 'float'
+ const float X::* const X::* pm2 = apm; // expected-note {{instantiation of}}
+ // This is correct: we don't need a qualification conversion, so we directly
+ // deduce T = 'const double'
+ const double X::* X::* pm1 = apm; // expected-note {{instantiation of}}
}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p5.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p5.cpp
new file mode 100644
index 0000000000000..8821d538dcbed
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p5.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T, bool B> using Fn = T () noexcept(B);
+
+// - If the original A is a function pointer type, A can be "pointer to
+// function" even if the deduced A is "pointer to noexcept function".
+struct A {
+ template<typename T> operator Fn<T, false>*(); // expected-note {{candidate}}
+};
+struct B {
+ template<typename T> operator Fn<T, true>*();
+};
+void (*p1)() = A();
+void (*p2)() = B();
+void (*p3)() noexcept = A(); // expected-error {{no viable conversion}}
+void (*p4)() noexcept = B();
+
+// - If the original A is a pointer to member function type, A can be "pointer
+// to member of type function" even if the deduced A is "pointer to member of
+// type noexcept function".
+struct C {
+ template<typename T> operator Fn<T, false> A::*(); // expected-note {{candidate}}
+};
+struct D {
+ template<typename T> operator Fn<T, true> A::*();
+};
+void (A::*q1)() = C();
+void (A::*q2)() = D();
+void (A::*q3)() noexcept = C(); // expected-error {{no viable conversion}}
+void (A::*q4)() noexcept = D();
+
+// There is no corresponding rule for references.
+// FIXME: This seems like a defect.
+// FIXME: We don't actually implement the final check for equal types at all!
+// Instead, we handle the matching via [over.ics.user]p3:
+// "If the user-defined conversion is specified by a specialization of a
+// conversion function template, the second standard conversion sequence
+// shall have exact match rank."
+// Note that this *does* allow discarding noexcept, since that conversion has
+// Exact Match rank.
+struct E {
+ template<typename T> operator Fn<T, false>&(); // expected-note {{candidate}}
+};
+struct F {
+ template<typename T> operator Fn<T, true>&();
+};
+void (&r1)() = E();
+void (&r2)() = F();
+void (&r3)() noexcept = E(); // expected-error {{no viable conversion}}
+void (&r4)() noexcept = F();
+
+// FIXME: We reject this for entirely the wrong reason. We incorrectly succeed
+// in deducing T = void, U = G::B, and only fail due to [over.ics.user]p3.
+struct G {
+ template<typename, typename> struct A {};
+ template<typename U> struct A<U, int> : A<U, void> {};
+ struct B { typedef int type; };
+
+ template<typename T, typename U = B> operator A<T, typename U::type> *(); // expected-note {{candidate function [with T = void, U = G::B]}}
+};
+G::A<void, void> *g = G(); // expected-error {{no viable conversion}}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
index b807a0ff9f112..54a54b0c486b6 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -32,7 +32,7 @@ namespace PackExpansionNotAtEnd {
template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
- struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
+ struct UselessPartialSpec<Types..., Tail>; // expected-error{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
}
namespace DeduceNonTypeTemplateArgsInArray {
diff --git a/test/CXX/temp/temp.spec/no-body.cpp b/test/CXX/temp/temp.spec/no-body.cpp
index 4ec18fdf820f4..6d1b82fe1898a 100644
--- a/test/CXX/temp/temp.spec/no-body.cpp
+++ b/test/CXX/temp/temp.spec/no-body.cpp
@@ -43,7 +43,7 @@ namespace good { // Only good in C++98/03
namespace unsupported {
#ifndef FIXING
- template struct y; // expected-error {{elaborated type refers to a template}}
+ template struct y; // expected-error {{template 'y' cannot be referenced with a struct specifier}}
#endif
}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
index d12feeff0bbca..ec2e380864bff 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
@@ -223,8 +223,8 @@ namespace spec_vs_expl_inst {
namespace SID {
template <typename STRING_TYPE> class BasicStringPiece;
- template <> class BasicStringPiece<int> { };
- template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}}
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous template specialization is here}}
+ template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}}
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
}
@@ -252,8 +252,8 @@ namespace spec_vs_expl_inst {
namespace DSI {
template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}}
- template <> class BasicStringPiece<int> { };
- template class BasicStringPiece<int>;
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous}}
+ template class BasicStringPiece<int>; // expected-warning {{has no effect}}
}
// The same again, with a defined template class.
@@ -267,8 +267,8 @@ namespace spec_vs_expl_inst {
namespace SID_WithDefinedTemplate {
template <typename STRING_TYPE> class BasicStringPiece {};
- template <> class BasicStringPiece<int> { };
- template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}}
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous}}
+ template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}}
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
}
@@ -283,7 +283,7 @@ namespace spec_vs_expl_inst {
template <typename STRING_TYPE> class BasicStringPiece {};
template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}}
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
- template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'BasicStringPiece<int>'}}
}
namespace DIS_WithDefinedTemplate {
@@ -304,23 +304,23 @@ namespace spec_vs_expl_inst {
namespace SII_WithDefinedTemplate {
template <typename STRING_TYPE> class BasicStringPiece {};
- template <> class BasicStringPiece<int> { };
- template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}}
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous}}
+ template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} expected-warning {{has no effect}}
template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}}
}
namespace SIS {
template <typename STRING_TYPE> class BasicStringPiece;
- template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
- template class BasicStringPiece<int>;
- template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}}
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} expected-note {{previous}}
+ template class BasicStringPiece<int>; // expected-warning {{has no effect}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'BasicStringPiece<int>'}}
}
namespace SDS {
template <typename STRING_TYPE> class BasicStringPiece;
template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
extern template class BasicStringPiece<int>;
- template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'BasicStringPiece<int>'}}
}
namespace SDIS {
@@ -328,7 +328,7 @@ namespace spec_vs_expl_inst {
template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
extern template class BasicStringPiece<int>;
template class BasicStringPiece<int>;
- template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'BasicStringPiece<int>'}}
}
}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
index 772aef6b585a4..ac040ccb3d645 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
@@ -1,6 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify %s
-struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate constructor (the implicit copy constructor)}}
+struct IntHolder { // expected-note 0-1{{here}} expected-note 2-4{{candidate constructor (the implicit}}
IntHolder(int); // expected-note 2{{candidate constructor}}
};
@@ -12,8 +14,13 @@ struct X { // expected-note{{here}}
void g() { }
- struct Inner { // expected-error{{implicit default}}
+ struct Inner {
+#if __cplusplus >= 201103L
+ T value; // expected-note {{has no default constructor}}
+#else
+ // expected-error@-4 {{implicit default}}
T value; // expected-note {{member is declared here}}
+#endif
};
static T value;
@@ -26,7 +33,12 @@ IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) {
xih.g(); // okay
xih.f(); // expected-note{{instantiation}}
- X<IntHolder, int>::Inner inner; // expected-note {{first required here}}
+ X<IntHolder, int>::Inner inner;
+#if __cplusplus >= 201103L
+ // expected-error@-2 {{call to implicitly-deleted}}
+#else
+ // expected-note@-4 {{first required here}}
+#endif
return X<IntHolder, int>::value; // expected-note{{instantiation}}
}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
index 09c428e01df3b..0a8a0ce9ff18e 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<typename T> void f0(T); // expected-note{{here}}
template void f0(int); // expected-error{{explicit instantiation of undefined function template}}
@@ -17,19 +18,19 @@ template void X0<int>::f1(); // expected-error{{explicit instantiation of undefi
template int X0<int>::value; // expected-error{{explicit instantiation of undefined static data member}}
template<> void f0(long); // expected-note{{previous template specialization is here}}
-template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization will be ignored}}
+template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization has no effect}}
template<> void X0<long>::f1(); // expected-note{{previous template specialization is here}}
-template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}}
+template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization has no effect}}
template<> struct X0<long>::Inner; // expected-note{{previous template specialization is here}}
-template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}}
+template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization has no effect}}
template<> long X0<long>::value; // expected-note{{previous template specialization is here}}
-template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}}
+template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization has no effect}}
template<> struct X0<double>; // expected-note{{previous template specialization is here}}
-template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization will be ignored}}
+template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization has no effect}}
// PR 6458
namespace test0 {
@@ -43,6 +44,6 @@ namespace test0 {
// inappropriately instantiating this template.
void *ptr = x;
}
- extern template class foo<char>; // expected-warning {{extern templates are a C++11 extension}}
+ extern template class foo<char>; // expected-warning 0-1{{extern templates are a C++11 extension}}
template class foo<char>;
}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
index 38dc367b227eb..9bdccc8e73246 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns -emit-llvm -std=c++11 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes -emit-llvm -std=c++11 -o - %s | FileCheck %s
template<typename T>
struct X0 {