summaryrefslogtreecommitdiff
path: root/test/CXX
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:28 +0000
commit7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch)
treec72b9241553fc9966179aba84f90f17bfa9235c3 /test/CXX
parentb52119637f743680a99710ce5fdb6646da2772af (diff)
Notes
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp93
-rw-r--r--test/CXX/class.derived/class.abstract/p16.cpp8
-rw-r--r--test/CXX/class.derived/class.member.lookup/p10.cpp114
-rw-r--r--test/CXX/class.derived/class.member.lookup/p6.cpp10
-rw-r--r--test/CXX/class.derived/class.member.lookup/p7.cpp10
-rw-r--r--test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp65
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp37
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp10
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp8
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp14
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp35
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp18
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp45
-rw-r--r--test/CXX/drs/dr10xx.cpp24
-rw-r--r--test/CXX/drs/dr12xx.cpp20
-rw-r--r--test/CXX/drs/dr13xx.cpp99
-rw-r--r--test/CXX/drs/dr16xx.cpp118
-rw-r--r--test/CXX/drs/dr1xx.cpp6
-rw-r--r--test/CXX/drs/dr21xx.cpp24
-rw-r--r--test/CXX/drs/dr2xx.cpp8
-rw-r--r--test/CXX/drs/dr3xx.cpp13
-rw-r--r--test/CXX/drs/dr4xx.cpp4
-rw-r--r--test/CXX/drs/dr5xx.cpp18
-rw-r--r--test/CXX/expr/expr.post/expr.type.conv/p1.cpp10
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp2
-rw-r--r--test/CXX/over/over.match/over.match.best/p1.cpp24
-rw-r--r--test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp25
-rw-r--r--test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp41
-rw-r--r--test/CXX/special/class.dtor/p10-0x.cpp2
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp2
-rw-r--r--test/CXX/temp/temp.deduct.guide/p1.cpp108
-rw-r--r--test/CXX/temp/temp.deduct.guide/p2.cpp15
-rw-r--r--test/CXX/temp/temp.deduct.guide/p3.cpp72
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp53
-rw-r--r--test/CXX/temp/temp.res/p3.cpp38
-rw-r--r--test/CXX/temp/temp.res/temp.local/p1.cpp57
-rw-r--r--test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp2
44 files changed, 1169 insertions, 97 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
index f32b23976547..18b18834bb48 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
@@ -1,17 +1,25 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
struct X0 {
+ X0();
+ X0(int);
X0 f1();
X0 f2();
+ typedef int A;
+ typedef X0 B;
};
template<typename T>
-struct X1 {
+struct X1 : X0 {
+ X1();
X1<T>(int);
(X1<T>)(float);
X1 f2();
X1 f2(int);
X1 f2(float);
+ X1 f2(double);
+ X1 f2(short);
+ X1 f2(long);
};
// Error recovery: out-of-line constructors whose names have template arguments.
@@ -19,13 +27,88 @@ template<typename T> X1<T>::X1<T>(int) { } // expected-error{{out-of-line constr
template<typename T> (X1<T>::X1<T>)(float) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}}
// Error recovery: out-of-line constructor names intended to be types
-X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type wherever a constructor can be declared}}
+X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
struct X0::X0 X0::f2() { return X0(); }
-template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
-template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}}
+template<typename T> X1<T>::X1<T> X1<T>::f2() { } // expected-error{{missing 'typename'}}
+template<typename T> X1<T>::X1<T> (X1<T>::f2)(int) { } // expected-error{{missing 'typename'}}
template<typename T> struct X1<T>::X1<T> (X1<T>::f2)(float) { }
+template<typename T> struct X1<T>::X1 (X1<T>::f2)(double) { }
+template<typename T> typename X1<T>::template X1<T> X1<T>::f2(short) { } // expected-warning {{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+template<typename T> typename X1<T>::template X1<T> (X1<T>::f2)(long) { } // expected-warning {{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+
+void x1test(X1<int> x1i) {
+ x1i.f2();
+ x1i.f2(0);
+ x1i.f2(0.f);
+ x1i.f2(0.);
+}
+
+void other_contexts() {
+ X0::X0 x0; // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+ X1<int>::X1 x1a; // expected-error{{qualified reference to 'X1' is a constructor name rather than a type in this context}}
+ X1<int>::X1<float> x1b; // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+
+ X0::B ok1;
+ X0::X0::A ok2;
+ X0::X0::X0 x0b; // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+ X1<int>::X0 ok3;
+ X1<int>::X0::X0 x0c; // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+ X1<int>::X1<float>::X0 ok4;
+
+ {
+ typename X0::X0 tn1; // expected-warning{{qualified reference to 'X0' is a constructor name rather than a type in this context}} expected-warning 0-1{{typename}}
+ typename X1<int>::X1<float> tn2; // expected-warning{{qualified reference to 'X1' is a constructor name rather than a template name in this context}} expected-warning 0-1{{typename}}
+ typename X0::B ok1; // expected-warning 0-1{{typename}}
+ typename X1<int>::X0 ok2; // expected-warning 0-1{{typename}}
+ }
+
+ {
+ struct X0::X0 tag1;
+ struct X1<int>::X1 tag2;
+ struct X1<int>::X1<int> tag3;
+ }
+
+ int a;
+ {
+ X0::X0(a); // expected-error{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+ }
+}
+
+template<typename T> void in_instantiation_x0() {
+ typename T::X0 x0; // expected-warning{{qualified reference to 'X0' is a constructor name rather than a type in this context}}
+ typename T::A a;
+ typename T::B b;
+}
+template void in_instantiation_x0<X0>(); // expected-note {{instantiation of}}
+
+template<typename T> void in_instantiation_x1() {
+ typename T::X1 x1; // expected-warning{{qualified reference to 'X1' is a constructor name rather than a type in this context}}
+ typename T::template X1<int> x1i; // expected-warning{{qualified reference to 'X1' is a constructor name rather than a template name in this context}}
+ typename T::X0 x0;
+}
+template void in_instantiation_x1<X1<int> >(); // expected-note {{instantiation of}}
+
+namespace sfinae {
+ template<typename T> void f(typename T::X0 *) = delete; // expected-warning 0-1{{extension}}
+ template<typename T> void f(...);
+ void g() { f<X0>(0); }
+}
+
+namespace versus_injected_class_name {
+ template <typename T> struct A : T::B {
+ struct T::B *p;
+ typename T::B::type a;
+ A() : T::B() {}
+
+ typename T::B b; // expected-warning {{qualified reference to 'B' is a constructor name rather than a type in this context}}
+ };
+ struct B {
+ typedef int type;
+ };
+ template struct A<B>; // expected-note {{in instantiation of}}
+}
// We have a special case for lookup within using-declarations that are
// member-declarations: foo::bar::baz::baz always names baz's constructor
@@ -109,7 +192,7 @@ namespace InhCtor {
// FIXME: Consider reusing the same diagnostic between dependent and non-dependent contexts
typedef int I;
struct UsingInt {
- using I::I; // expected-error {{'I' (aka 'int') is not a class, namespace, or enumeration}}
+ using I::I; // expected-error {{'InhCtor::I' (aka 'int') is not a class, namespace, or enumeration}}
};
template<typename T> struct UsingIntTemplate {
using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
diff --git a/test/CXX/class.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp
index 29adbccac479..80396a96d9ec 100644
--- a/test/CXX/class.derived/class.abstract/p16.cpp
+++ b/test/CXX/class.derived/class.abstract/p16.cpp
@@ -35,13 +35,15 @@ 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}}
+// expected-note@-4 {{while declaring the implicit copy assignment operator for 'E'}}
+// expected-note@-5 {{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@-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-note@-2 {{destructor of 'G' 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 {{destructor of 'G' is implicitly deleted because base class 'D' has an inaccessible destructor}}
+// expected-note@-4 {{while declaring the implicit move assignment operator for 'G'}}
+// expected-note@-5 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
struct H : D {
H &operator=(H&&) = default;
// expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}}
diff --git a/test/CXX/class.derived/class.member.lookup/p10.cpp b/test/CXX/class.derived/class.member.lookup/p10.cpp
new file mode 100644
index 000000000000..afd87521885a
--- /dev/null
+++ b/test/CXX/class.derived/class.member.lookup/p10.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wshadow-all
+
+// Basic cases, ambiguous paths, and fields with different access
+class A {
+public:
+ int x; // expected-note 2{{declared here}}
+protected:
+ int y; // expected-note 2{{declared here}}
+private:
+ int z;
+};
+
+struct B : A {
+};
+
+struct C : A {
+};
+
+struct W {
+ int w; // expected-note {{declared here}}
+};
+
+struct U : W {
+};
+
+struct V : W {
+};
+
+class D {
+public:
+ char w; // expected-note {{declared here}}
+private:
+ char x;
+};
+
+// Check direct inheritance and multiple paths to the same base.
+class E : B, C, D, U, V
+{
+ unsigned x; // expected-warning {{non-static data member 'x' of 'E' shadows member inherited from type 'A'}}
+ char y; // expected-warning {{non-static data member 'y' of 'E' shadows member inherited from type 'A'}}
+ double z;
+ char w; // expected-warning {{non-static data member 'w' of 'E' shadows member inherited from type 'D'}} expected-warning {{non-static data member 'w' of 'E' shadows member inherited from type 'W'}}
+};
+
+// Virtual inheritance
+struct F : virtual A {
+};
+
+struct G : virtual A {
+};
+
+class H : F, G {
+ int x; // expected-warning {{non-static data member 'x' of 'H' shadows member inherited from type 'A'}}
+ int y; // expected-warning {{non-static data member 'y' of 'H' shadows member inherited from type 'A'}}
+ int z;
+};
+
+// Indirect inheritance
+struct I {
+ union {
+ int x; // expected-note {{declared here}}
+ int y;
+ };
+};
+
+struct J : I {
+ int x; // expected-warning {{non-static data member 'x' of 'J' shadows member inherited from type 'I'}}
+};
+
+// non-access paths
+class N : W {
+};
+
+struct K {
+ int y;
+};
+
+struct L : private K {
+};
+
+struct M : L {
+ int y;
+ int w;
+};
+
+// Multiple ambiguous paths with different accesses
+struct A1 {
+ int x; // expected-note {{declared here}}
+};
+
+class B1 : A1 {
+};
+
+struct B2 : A1 {
+};
+
+struct C1 : B1, B2 {
+};
+
+class D1 : C1 {
+};
+
+struct D2 : C1 {
+};
+
+class D3 : C1 {
+};
+
+struct E1 : D1, D2, D3{
+ int x; // expected-warning {{non-static data member 'x' of 'E1' shadows member inherited from type 'A1'}}
+};
+
+
+
diff --git a/test/CXX/class.derived/class.member.lookup/p6.cpp b/test/CXX/class.derived/class.member.lookup/p6.cpp
index 72398819263f..0a400a2405e9 100644
--- a/test/CXX/class.derived/class.member.lookup/p6.cpp
+++ b/test/CXX/class.derived/class.member.lookup/p6.cpp
@@ -1,24 +1,24 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wshadow-field
class V {
public:
int f();
- int x;
+ int x; // expected-note {{declared here}}
};
class W {
public:
int g(); // expected-note{{member found by ambiguous name lookup}}
- int y; // expected-note{{member found by ambiguous name lookup}}
+ int y; // expected-note{{member found by ambiguous name lookup}} expected-note {{declared here}}
};
class B : public virtual V, public W
{
public:
int f();
- int x;
+ int x; // expected-warning {{non-static data member 'x' of 'B' shadows member inherited from type 'V'}}
int g(); // expected-note{{member found by ambiguous name lookup}}
- int y; // expected-note{{member found by ambiguous name lookup}}
+ int y; // expected-note{{member found by ambiguous name lookup}} expected-warning {{non-static data member 'y' of 'B' shadows member inherited from type 'W'}}
};
class C : public virtual V, public W { };
diff --git a/test/CXX/class.derived/class.member.lookup/p7.cpp b/test/CXX/class.derived/class.member.lookup/p7.cpp
index a785e0f90e57..775057792c5c 100644
--- a/test/CXX/class.derived/class.member.lookup/p7.cpp
+++ b/test/CXX/class.derived/class.member.lookup/p7.cpp
@@ -1,11 +1,9 @@
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify %s -Wshadow-field
-// expected-no-diagnostics
-
-struct A { int n; };
-struct B { float n; };
+struct A { int n; }; // expected-note {{declared here}}
+struct B { float n; }; // expected-note {{declared here}}
struct C : A, B {};
struct D : virtual C {};
-struct E : virtual C { char n; };
+struct E : virtual C { char n; }; // expected-warning {{non-static data member 'n' of 'E' shadows member inherited from type 'A'}} expected-warning {{non-static data member 'n' of 'E' shadows member inherited from type 'B'}}
struct F : D, E {} f;
char &k = f.n;
diff --git a/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp b/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
new file mode 100644
index 000000000000..d1ad0404ef42
--- /dev/null
+++ b/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+
+namespace nodiag {
+
+template <typename T> requires bool(T())
+struct A;
+template <typename U> requires bool(U())
+struct A;
+
+} // end namespace nodiag
+
+namespace diag {
+
+template <typename T> requires true // expected-note{{previous template declaration is here}}
+struct A;
+template <typename T> struct A; // expected-error{{associated constraints differ in template redeclaration}}
+
+template <typename T> struct B; // expected-note{{previous template declaration is here}}
+template <typename T> requires true // expected-error{{associated constraints differ in template redeclaration}}
+struct B;
+
+template <typename T> requires true // expected-note{{previous template declaration is here}}
+struct C;
+template <typename T> requires !0 // expected-error{{associated constraints differ in template redeclaration}}
+struct C;
+
+} // end namespace diag
+
+namespace nodiag {
+
+struct AA {
+ template <typename T> requires someFunc(T())
+ struct A;
+};
+
+template <typename T> requires someFunc(T())
+struct AA::A { };
+
+struct AAF {
+ template <typename T> requires someFunc(T())
+ friend struct AA::A;
+};
+
+} // end namespace nodiag
+
+namespace diag {
+
+template <unsigned N>
+struct TA {
+ template <template <unsigned> class TT> requires TT<N>::happy // expected-note 2{{previous template declaration is here}}
+ struct A;
+
+ struct AF;
+};
+
+template <unsigned N>
+template <template <unsigned> class TT> struct TA<N>::A { }; // expected-error{{associated constraints differ in template redeclaration}}
+
+template <unsigned N>
+struct TA<N>::AF {
+ template <template <unsigned> class TT> requires TT<N + 0>::happy // expected-error{{associated constraints differ in template redeclaration}}
+ friend struct TA::A;
+};
+
+} // end namespace diag
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
index a27cea84db45..58c7c0cfac8b 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -23,7 +23,38 @@ template <> class [[deprecated]] X<int> {}; // expected-note {{'X<int>' has been
X<char> x1;
X<int> x2; // expected-warning {{'X<int>' is deprecated}}
-template <typename T> class [[deprecated]] X2 {};
+template <typename T> class [[deprecated]] X2 {}; //expected-note {{'X2<char>' has been explicitly marked deprecated here}}
template <> class X2<int> {};
-X2<char> x3; // FIXME: no warning!
-X2<int> x4;
+X2<char> x3; // expected-warning {{'X2<char>' is deprecated}}
+X2<int> x4; // No warning, the specialization removes it.
+
+template <typename T> class [[deprecated]] X3; //expected-note {{'X3<char>' has been explicitly marked deprecated here}}
+template <> class X3<int>;
+X3<char> *x5; // expected-warning {{'X3<char>' is deprecated}}
+X3<int> *x6; // No warning, the specialization removes it.
+
+template <typename T> struct A;
+A<int> *p;
+template <typename T> struct [[deprecated]] A;//expected-note {{'A<int>' has been explicitly marked deprecated here}} expected-note {{'A<float>' has been explicitly marked deprecated here}}
+A<int> *q; // expected-warning {{'A<int>' is deprecated}}
+A<float> *r; // expected-warning {{'A<float>' is deprecated}}
+
+template <typename T> struct B;
+B<int> *p2;
+template <typename T> struct [[deprecated]] B;//expected-note {{'B<int>' has been explicitly marked deprecated here}} expected-note {{'B<float>' has been explicitly marked deprecated here}}
+B<int> *q2; // expected-warning {{'B<int>' is deprecated}}
+B<float> *r2; // expected-warning {{'B<float>' is deprecated}}
+
+template <typename T>
+T some_func(T t) {
+ struct [[deprecated]] FunS{}; // expected-note {{'FunS' has been explicitly marked deprecated here}}
+ FunS f;// expected-warning {{'FunS' is deprecated}}
+
+}
+
+template <typename T>
+[[deprecated]]T some_func2(T t) {
+ struct FunS2{};
+ FunS2 f;// No warning, entire function is deprecated, so usage here should be fine.
+
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
index eb751517e2f2..e8f12156a424 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
@@ -3,15 +3,15 @@
// FIXME: This is in p11 (?) in C++1y.
void f() {
- decltype(auto) a = a; // expected-error{{variable 'a' declared with 'decltype(auto)' type cannot appear in its own initializer}}
- if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'decltype(auto)' type cannot appear in its own initializer}}
- decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with 'decltype(auto)' type cannot appear in its own initializer}}
+ decltype(auto) a = a; // expected-error{{variable 'a' declared with deduced type 'decltype(auto)' cannot appear in its own initializer}}
+ if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with deduced type 'decltype(auto)' cannot appear in its own initializer}}
+ decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with deduced type 'decltype(auto)' cannot appear in its own initializer}}
}
void g() {
- decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}}
+ decltype(auto) a; // expected-error{{declaration of variable 'a' with deduced type 'decltype(auto)' requires an initializer}}
- decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}}
+ decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with deduced type 'decltype(auto) *' requires an initializer}}
if (decltype(auto) b) {} // expected-error {{must have an initializer}}
for (;decltype(auto) b;) {} // expected-error {{must have an initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp
new file mode 100644
index 000000000000..73caa2de044e
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1z.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z
+
+// FIXME: This is in p10 (?) in C++1z.
+template<typename T> struct A {
+ A(T);
+};
+template<typename T> A(T) -> A<T>;
+A a = a; // expected-error{{variable 'a' declared with deduced type 'A' cannot appear in its own initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
index e91cacf10466..440c78201293 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
@@ -1,17 +1,17 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions -Wc++11-compat
void f() {
- auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
- auto *b = b; // expected-error{{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
- const auto c = c; // expected-error{{variable 'c' declared with 'auto' type cannot appear in its own initializer}}
- if (auto d = d) {} // expected-error {{variable 'd' declared with 'auto' type cannot appear in its own initializer}}
- auto e = ({ auto f = e; 0; }); // expected-error {{variable 'e' declared with 'auto' type cannot appear in its own initializer}}
+ auto a = a; // expected-error{{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+ auto *b = b; // expected-error{{variable 'b' declared with deduced type 'auto *' cannot appear in its own initializer}}
+ const auto c = c; // expected-error{{variable 'c' declared with deduced type 'const auto' cannot appear in its own initializer}}
+ if (auto d = d) {} // expected-error {{variable 'd' declared with deduced type 'auto' cannot appear in its own initializer}}
+ auto e = ({ auto f = e; 0; }); // expected-error {{variable 'e' declared with deduced type 'auto' cannot appear in its own initializer}}
}
void g() {
- auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+ auto a; // expected-error{{declaration of variable 'a' with deduced type 'auto' requires an initializer}}
- auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
+ auto *b; // expected-error{{declaration of variable 'b' with deduced type 'auto *' requires an initializer}}
if (auto b) {} // expected-error {{must have an initializer}}
for (;auto b;) {} // expected-error {{must have an initializer}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
index 46c874f605cb..bf1b3092e08e 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
@@ -36,7 +36,7 @@ class X {
};
struct S {
- static const auto a; // expected-error {{declaration of variable 'a' with type 'const auto' requires an initializer}}
+ static const auto a; // expected-error {{declaration of variable 'a' with deduced type 'const auto' requires an initializer}}
static const auto b = 0;
static const int c;
};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
index 0cdf3c6e053f..a260f99f5cf1 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -9,7 +9,7 @@ struct S {
void f() throw (auto); // expected-error{{'auto' not allowed here}}
- friend auto; // expected-error{{'auto' not allowed in non-static struct member}}
+ friend auto; // expected-error{{'auto' not allowed in friend declaration}}
operator auto(); // expected-error{{'auto' not allowed in conversion function type}}
};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
index 06bd72e125d1..60ddabeb4a90 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
@@ -51,7 +51,7 @@ decltype(auto) *f3(); // expected-error {{cannot form pointer to 'decltype(auto)
const decltype(auto) f4(); // expected-error {{'decltype(auto)' cannot be combined with other type specifiers}}
typedef decltype(auto) f5(); // expected-error {{'decltype(auto)' not allowed in typedef}}
decltype(auto) ((((((f6))))())); // ok
-decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{function cannot return function type}}
+decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}}
decltype(auto) (S::*f8)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}}
decltype(auto) &f9(); // expected-error {{cannot form reference to 'decltype(auto)'}}
decltype(auto) (&f10())[10]; // expected-error {{cannot form array of 'decltype(auto)'}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
index 8d789bdd5ad3..e9294d7f4362 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
void f() {
@@ -19,22 +20,42 @@ void f() {
}
void g() {
- auto a = 0,
#if __has_feature(cxx_trailing_return)
- (*b)() -> void,
-#endif
+ auto a = 0,
+ (*b)() -> void, // expected-error {{declaration with trailing return type must be the only declaration in its group}}
c = 0;
- auto d = 0, // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}}
-#if __has_feature(cxx_trailing_return)
- (*e)() -> void,
-#endif
+ auto d = 0,
+ e() -> void, // expected-error {{declaration with trailing return type must be the only declaration in its group}}
f = 0.0;
+ auto x() -> void, // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+ y() -> void;
+#endif
#if __has_feature(cxx_decltype)
auto g = 0ull, h = decltype(g)(0);
#endif
}
+#if __has_feature(cxx_trailing_return)
+int F();
+auto p = 0, (*q)() -> auto = F; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+ #if __cplusplus < 201402L
+ // expected-error@-2 {{'auto' not allowed in function return type}}
+ #endif
+#endif
+
+#if __cplusplus >= 201402L
+namespace DeducedReturnType {
+ auto a = 0,
+ b(), // expected-error {{function with deduced return type must be the only declaration in its group}}
+ c = 0.0;
+ auto d(), // expected-error {{function with deduced return type must be the only declaration in its group}}
+ e = 1;
+ auto f(), // expected-error {{function with deduced return type must be the only declaration in its group}}
+ g();
+}
+#endif
+
template<typename T> void h() {
auto a = T(), *b = &a;
#if __has_feature(cxx_decltype)
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
new file mode 100644
index 000000000000..cfb9a61f1ac4
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T> struct A { constexpr A(int = 0) {} };
+A() -> A<int>;
+A(int) -> A<char>;
+
+static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
+// FIXME: There isn't really a good reason to reject this.
+A b; // expected-error {{requires an initializer}}
+A c [[]] {};
+
+A d = {}, e = {};
+A f(0), g{}; // expected-error {{template arguments deduced as 'A<char>' in declaration of 'f' and deduced as 'A<int>' in declaration of 'g'}}
+
+struct B {
+ static A a; // expected-error {{requires an initializer}}
+};
+extern A x; // expected-error {{requires an initializer}}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
index f381ed708f70..ade327485773 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
@@ -150,35 +150,44 @@ namespace cxx1z_direct_enum_init {
void f(T);
f(T{0});
+
+ char c;
+ auto t3 = T{c};
}
#if __cplusplus <= 201402L
- // expected-error@-15 5{{cannot initialize}}
- // expected-error@-15 5{{cannot initialize}}
- // expected-error@-15 5{{cannot initialize}}
+ // expected-error@-18 5{{cannot initialize}}
+ // expected-error@-18 5{{cannot initialize}}
+ // expected-error@-18 5{{cannot initialize}}
+ //
//
+ // expected-error@-18 5{{cannot initialize}}
//
- // expected-error@-15 5{{cannot initialize}}
+ // expected-error@-18 5{{cannot initialize}}
//
- // expected-error@-15 5{{cannot initialize}}
+ // expected-error@-18 5{{cannot initialize}}
//
- // expected-error@-15 5{{cannot initialize}}
//
+ // expected-error@-18 5{{cannot initialize}}
//
- // expected-error@-15 5{{cannot initialize}}
+ //
+ // expected-error@-18 5{{cannot initialize}}
#else
- // expected-error@-29 {{cannot initialize}}
- // expected-error@-29 {{cannot initialize}}
- // expected-error@-29 {{cannot initialize}}
+ // expected-error@-35 {{cannot initialize}}
+ // expected-error@-35 {{cannot initialize}}
+ // expected-error@-35 {{cannot initialize}}
+ //
//
+ // expected-error@-35 {{cannot initialize}}
//
- // expected-error@-29 {{cannot initialize}}
+ // expected-error@-35 {{cannot initialize}}
//
- // expected-error@-29 {{cannot initialize}}
+ // expected-error@-35 {{cannot initialize}}
//
- // expected-error@-29 {{cannot initialize}}
//
+ // expected-error@-35 {{cannot initialize}}
//
- // expected-error@-29 {{cannot initialize}}
+ //
+ // expected-error@-35 {{cannot initialize}}
#endif
template<typename T> void bad() {
@@ -252,4 +261,12 @@ namespace cxx1z_direct_enum_init {
(void)B{0.0}; // expected-error {{type 'double' cannot be narrowed}}
#endif
}
+
+#if __cplusplus > 201402L
+ enum class F : unsigned {};
+ F f1(unsigned x) { return F{x}; }
+ F f2(const unsigned x) { return F{x}; }
+ F f3(bool x) { return F{x}; }
+ F f4(const bool x) { return F{x}; }
+#endif
}
diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp
index e11e796165e2..e1db9ef54adf 100644
--- a/test/CXX/drs/dr10xx.cpp
+++ b/test/CXX/drs/dr10xx.cpp
@@ -12,6 +12,30 @@ namespace std {
};
}
+namespace dr1004 { // dr1004: 5
+ template<typename> struct A {};
+ template<typename> struct B1 {};
+ template<template<typename> class> struct B2 {};
+ template<typename X> void f(); // expected-note {{[with X = dr1004::A<int>]}}
+ template<template<typename> class X> void f(); // expected-note {{[with X = A]}}
+ template<template<typename> class X> void g(); // expected-note {{[with X = A]}}
+ template<typename X> void g(); // expected-note {{[with X = dr1004::A<int>]}}
+ struct C : A<int> {
+ B1<A> b1a;
+ B2<A> b2a;
+ void h() {
+ f<A>(); // expected-error {{ambiguous}}
+ g<A>(); // expected-error {{ambiguous}}
+ }
+ };
+
+ // This example (from the standard) is actually ill-formed, because
+ // name lookup of "T::template A" names the constructor.
+ // FIXME: Only issue one diagnostic for this case.
+ template<class T, template<class> class U = T::template A> struct Third { }; // expected-error 2{{is a constructor name}}
+ Third<A<int> > t; // expected-note {{in instantiation of}} expected-note {{while substituting}} expected-note {{while checking}}
+}
+
namespace dr1048 { // dr1048: 3.6
struct A {};
const A f();
diff --git a/test/CXX/drs/dr12xx.cpp b/test/CXX/drs/dr12xx.cpp
index 45b33f9d7daf..24039a1cd240 100644
--- a/test/CXX/drs/dr12xx.cpp
+++ b/test/CXX/drs/dr12xx.cpp
@@ -14,7 +14,7 @@ namespace dr1213 { // dr1213: 4
#endif
}
-namespace dr1250 { // dr1250: 3.9
+namespace dr1250 { // dr1250: 3.9
struct Incomplete;
struct Base {
@@ -24,9 +24,23 @@ struct Base {
struct Derived : Base {
virtual Incomplete *meow();
};
-} // dr1250
+}
+
+namespace dr1265 { // dr1265: 5
+#if __cplusplus >= 201103L
+ auto a = 0, b() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+ auto b() -> int, d = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+ auto e() -> int, f() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+#endif
+
+#if __cplusplus >= 201402L
+ auto g(), h = 0; // expected-error {{function with deduced return type must be the only declaration in its group}}
+ auto i = 0, j(); // expected-error {{function with deduced return type must be the only declaration in its group}}
+ auto k(), l(); // expected-error {{function with deduced return type must be the only declaration in its group}}
+#endif
+}
-namespace dr1295 { // dr1295: 4
+namespace dr1295 { // dr1295: 4
struct X {
unsigned bitfield : 4;
};
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
index f35ead7b5e94..56ff1237480f 100644
--- a/test/CXX/drs/dr13xx.cpp
+++ b/test/CXX/drs/dr13xx.cpp
@@ -3,6 +3,96 @@
// 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
+__extension__ typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+ template<typename T> struct initializer_list {
+ const T *ptr;
+ size_t n;
+ initializer_list(const T*, size_t);
+ };
+}
+
+namespace dr1310 { // dr1310: 5
+ struct S {} * sp = new S::S; // expected-error {{qualified reference to 'S' is a constructor name}}
+ void f() {
+ S::S(a); // expected-error {{qualified reference to 'S' is a constructor name}}
+ }
+ struct T { int n; typedef int U; typedef T V; };
+ int k = T().T::T::n;
+ T::V v;
+
+ struct U { int U; };
+ int u = U().U::U;
+ struct U::U w;
+
+ struct V : T::T {
+ // FIXME: This is technically ill-formed, but we consider that to be a defect.
+ V() : T::T() {}
+ };
+ template<typename T> struct VT : T::T {
+ VT() : T::T() {}
+ };
+ template struct VT<T>;
+
+ template<template<typename> class> class TT {};
+ template<typename> class TTy {};
+
+ template<typename T> struct WBase {};
+ template<typename T> struct W : WBase<T> { typedef int X; int n; };
+
+ void w_test() {
+ W<int>::W w1a; // expected-error {{qualified reference to 'W' is a constructor name}}
+ W<int>::W::X w1ax;
+ W<int>::W<int> w1b; // expected-error {{qualified reference to 'W' is a constructor name}}
+ W<int>::W<int>::X w1bx;
+ typename W<int>::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+ typename W<int>::W::X w2ax; // expected-error 0-1{{outside of a template}}
+ typename W<int>::W<int> w2b; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+ typename W<int>::W<int>::X w2bx; // expected-error 0-1{{outside of a template}}
+ W<int>::template W<int> w3; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+ W<int>::template W<int>::X w3x; // expected-error 0-1{{outside of a template}}
+ typename W<int>::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-2{{outside of a template}}
+ typename W<int>::template W<int>::X w4x; // expected-error 0-2{{outside of a template}}
+
+ TT<W<int>::W> tt1; // expected-error {{qualified reference to 'W' is a constructor name}}
+ TTy<W<int>::W> tt1a; // expected-error {{qualified reference to 'W' is a constructor name}}
+ TT<W<int>::template W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+ TT<W<int>::WBase> tt3;
+ TTy<W<int>::WBase> tt3a;
+ TT<W<int>::template WBase> tt4; // expected-error 0-1{{outside of a template}}
+
+ W<int> w;
+ (void)w.W::W::n;
+ (void)w.W<int>::W::n;
+ (void)w.W<int>::W<int>::n;
+ (void)w.W<int>::template W<int>::n; // expected-error 0-1{{outside of a template}}
+ }
+
+ template<typename W>
+ void wt_test() {
+ typename W::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}}
+ typename W::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}}
+ TTy<typename W::W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}}
+ TT<W::template W> tt3; // expected-error {{qualified reference to 'W' is a constructor name}}
+ }
+ template<typename W>
+ void wt_test_good() {
+ typename W::W::X w2ax;
+ typename W::template W<int>::X w4x;
+ TTy<typename W::WBase> tt4;
+ TT<W::template WBase> tt5;
+
+ W w;
+ (void)w.W::W::n;
+ (void)w.W::template W<int>::n;
+ (void)w.template W<int>::W::n;
+ (void)w.template W<int>::template W<int>::n;
+ }
+ template void wt_test<W<int> >(); // expected-note {{instantiation of}}
+ template void wt_test_good<W<int> >();
+}
+
namespace dr1315 { // dr1315: partial
template <int I, int J> struct A {};
template <int I> // expected-note {{non-deducible template parameter 'I'}}
@@ -159,6 +249,15 @@ namespace dr1346 { // dr1346: 3.5
#endif
}
+namespace dr1347 { // dr1347: yes
+ auto x = 5, *y = &x; // expected-error 0-1{{extension}}
+ auto z = y, *q = y; // expected-error {{'auto' deduced as 'int *' in declaration of 'z' and deduced as 'int' in declaration of 'q'}} expected-error 0-1{{extension}}
+#if __cplusplus >= 201103L
+ auto a = 5, b = {1, 2}; // expected-error {{'auto' deduced as 'int' in declaration of 'a' and deduced as 'std::initializer_list<int>' in declaration of 'b'}}
+ auto (*fp)(int) -> int, i = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+#endif
+}
+
namespace dr1359 { // dr1359: 3.5
#if __cplusplus >= 201103L
union A { constexpr A() = default; };
diff --git a/test/CXX/drs/dr16xx.cpp b/test/CXX/drs/dr16xx.cpp
index c9f084db73a1..08ae92570cec 100644
--- a/test/CXX/drs/dr16xx.cpp
+++ b/test/CXX/drs/dr16xx.cpp
@@ -3,6 +3,13 @@
// 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
+namespace dr1611 { // dr1611: dup 1658
+ struct A { A(int); };
+ struct B : virtual A { virtual void f() = 0; };
+ struct C : B { C() : A(0) {} void f(); };
+ C c;
+}
+
namespace dr1684 { // dr1684: 3.6
#if __cplusplus >= 201103L
struct NonLiteral { // expected-note {{because}}
@@ -101,3 +108,114 @@ namespace dr1653 { // dr1653: 4 c++17
b -= 1; // ok
}
}
+
+namespace dr1658 { // dr1658: 5
+ namespace DefCtor {
+ class A { A(); }; // expected-note 0-2{{here}}
+ class B { ~B(); }; // expected-note 0-2{{here}}
+
+ // The stars align! An abstract class does not construct its virtual bases.
+ struct C : virtual A { C(); virtual void foo() = 0; };
+ C::C() = default; // ok, not deleted, expected-error 0-1{{extension}}
+ struct D : virtual B { D(); virtual void foo() = 0; };
+ D::D() = default; // ok, not deleted, expected-error 0-1{{extension}}
+
+ // In all other cases, we are not so lucky.
+ struct E : A { E(); virtual void foo() = 0; };
+#if __cplusplus < 201103L
+ E::E() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}}
+#else
+ E::E() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}}
+#endif
+ struct F : virtual A { F(); };
+#if __cplusplus < 201103L
+ F::F() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}}
+#else
+ F::F() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}}
+#endif
+
+ struct G : B { G(); virtual void foo() = 0; };
+#if __cplusplus < 201103L
+ G::G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+ G::G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+ struct H : virtual B { H(); };
+#if __cplusplus < 201103L
+ H::H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+ H::H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+ }
+
+ namespace Dtor {
+ class B { ~B(); }; // expected-note 0-2{{here}}
+
+ struct D : virtual B { ~D(); virtual void foo() = 0; };
+ D::~D() = default; // ok, not deleted, expected-error 0-1{{extension}}
+
+ struct G : B { ~G(); virtual void foo() = 0; };
+#if __cplusplus < 201103L
+ G::~G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+ G::~G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+ struct H : virtual B { ~H(); };
+#if __cplusplus < 201103L
+ H::~H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}
+#else
+ H::~H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}
+#endif
+ }
+
+ namespace MemInit {
+ struct A { A(int); }; // expected-note {{here}}
+ struct B : virtual A {
+ B() {}
+ virtual void f() = 0;
+ };
+ struct C : virtual A {
+ C() {} // expected-error {{must explicitly initialize}}
+ };
+ }
+
+ namespace CopyCtorParamType {
+ struct A { A(A&); };
+ struct B : virtual A { virtual void f() = 0; };
+ struct C : virtual A { virtual void f(); };
+ struct D : A { virtual void f() = 0; };
+
+ struct X {
+ friend B::B(const B&) throw();
+ friend C::C(C&);
+ friend D::D(D&);
+ };
+ }
+
+ namespace CopyCtor {
+ class A { A(const A&); A(A&&); }; // expected-note 0-4{{here}} expected-error 0-1{{extension}}
+
+ struct C : virtual A { C(const C&); C(C&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}}
+ C::C(const C&) = default; // expected-error 0-1{{extension}}
+ C::C(C&&) = default; // expected-error 0-2{{extension}}
+
+ struct E : A { E(const E&); E(E&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}}
+#if __cplusplus < 201103L
+ E::E(const E&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}}
+ E::E(E&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}}
+#else
+ E::E(const E&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}}
+ E::E(E&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}}
+#endif
+ struct F : virtual A { F(const F&); F(F&&); }; // expected-error 0-1{{extension}}
+#if __cplusplus < 201103L
+ F::F(const F&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}}
+ F::F(F&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}}
+#else
+ F::F(const F&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}}
+ F::F(F&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}}
+#endif
+ }
+
+ // assignment case is superseded by dr2180
+}
diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index 9521f0a8b784..f5395cfe183d 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/test/CXX/drs/dr1xx.cpp
@@ -535,13 +535,15 @@ namespace dr145 { // dr145: yes
}
}
-namespace dr147 { // dr147: no
+namespace dr147 { // dr147: yes
namespace example1 {
template<typename> struct A {
template<typename T> A(T);
};
- // FIXME: This appears to be valid, and EDG and G++ accept.
+ // Per core issue 1435, this is ill-formed because A<int>::A<int> does not
+ // name the injected-class-name. (A<int>::A does, though.)
template<> template<> A<int>::A<int>(int) {} // expected-error {{out-of-line constructor for 'A' cannot have template arguments}}
+ template<> template<> A<float>::A(float) {}
}
namespace example2 {
struct A { A(); };
diff --git a/test/CXX/drs/dr21xx.cpp b/test/CXX/drs/dr21xx.cpp
new file mode 100644
index 000000000000..78fc0bec40bf
--- /dev/null
+++ b/test/CXX/drs/dr21xx.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// 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
+
+namespace dr2180 { // dr2180: yes
+ class A {
+ A &operator=(const A &); // expected-note 0-2{{here}}
+ A &operator=(A &&); // expected-note 0-2{{here}} expected-error 0-1{{extension}}
+ };
+
+ struct B : virtual A {
+ B &operator=(const B &);
+ B &operator=(B &&); // expected-error 0-1{{extension}}
+ virtual void foo() = 0;
+ };
+#if __cplusplus < 201103L
+ B &B::operator=(const B&) = default; // expected-error {{private member}} expected-error {{extension}} expected-note {{here}}
+ B &B::operator=(B&&) = default; // expected-error {{private member}} expected-error 2{{extension}} expected-note {{here}}
+#else
+ B &B::operator=(const B&) = default; // expected-error {{would delete}} expected-note@-9{{inaccessible copy assignment}}
+ B &B::operator=(B&&) = default; // expected-error {{would delete}} expected-note@-10{{inaccessible move assignment}}
+#endif
+}
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index 68261f6c00f1..a5677a125a00 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -1014,7 +1014,7 @@ namespace dr294 { // dr294: no
namespace dr295 { // dr295: 3.7
typedef int f();
- const f g; // expected-warning {{'const' qualifier on function type 'f' (aka 'int ()') has no effect}}
+ const f g; // expected-warning {{'const' qualifier on function type 'dr295::f' (aka 'int ()') has no effect}}
f &r = g;
template<typename T> struct X {
const T &f;
@@ -1022,10 +1022,10 @@ namespace dr295 { // dr295: 3.7
X<f> x = {g};
typedef int U();
- typedef const U U; // expected-warning {{'const' qualifier on function type 'U' (aka 'int ()') has no effect}}
+ typedef const U U; // expected-warning {{'const' qualifier on function type 'dr295::U' (aka 'int ()') has no effect}}
typedef int (*V)();
- typedef volatile U *V; // expected-warning {{'volatile' qualifier on function type 'U' (aka 'int ()') has no effect}}
+ typedef volatile U *V; // expected-warning {{'volatile' qualifier on function type 'dr295::U' (aka 'int ()') has no effect}}
}
namespace dr296 { // dr296: yes
@@ -1053,7 +1053,7 @@ namespace dr298 { // dr298: yes
B::B() {} // expected-error {{requires a type specifier}}
B::A() {} // ok
- C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'C' (aka 'const dr298::A') of the class name}}
+ C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'dr298::C' (aka 'const dr298::A') of the class name}}
typedef struct D E; // expected-note {{here}}
struct E {}; // expected-error {{conflicts with typedef}}
diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp
index a1c1c4ce6132..3342148461ad 100644
--- a/test/CXX/drs/dr3xx.cpp
+++ b/test/CXX/drs/dr3xx.cpp
@@ -908,18 +908,21 @@ namespace dr372 { // dr372: no
}
}
-namespace dr373 { // dr373: no
- // FIXME: This is valid.
- namespace X { int dr373; } // expected-note 2{{here}}
+namespace dr373 { // dr373: 5
+ namespace X { int dr373; }
struct dr373 { // expected-note {{here}}
void f() {
- using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}}
+ using namespace dr373::X;
int k = dr373; // expected-error {{does not refer to a value}}
- namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}}
+ namespace Y = dr373::X;
k = Y::dr373;
}
};
+
+ struct A { struct B {}; }; // expected-note 2{{here}}
+ namespace X = A::B; // expected-error {{expected namespace name}}
+ using namespace A::B; // expected-error {{expected namespace name}}
}
namespace dr374 { // dr374: yes c++11
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp
index 6046c4afefd5..3ea226a745f6 100644
--- a/test/CXX/drs/dr4xx.cpp
+++ b/test/CXX/drs/dr4xx.cpp
@@ -35,9 +35,7 @@ namespace dr401 { // dr401: yes
};
A<B> *b; // expected-note {{default argument}}
- // FIXME: We're missing the "in instantiation of" note for the default
- // argument here.
- A<D> *d;
+ A<D> *d; // expected-note {{in instantiation of default argument}}
struct E {
template<class T, class U = typename T::type> class A : public T {};
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
index 89e404f5fd6d..97b40b8b7c26 100644
--- a/test/CXX/drs/dr5xx.cpp
+++ b/test/CXX/drs/dr5xx.cpp
@@ -877,13 +877,25 @@ namespace dr583 { // dr583: 4
namespace dr585 { // dr585: yes
template<typename> struct T;
struct A {
- friend T; // expected-error {{requires a type specifier}} expected-error {{can only be classes or functions}}
+ friend T;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{requires a type specifier}} expected-error@-2 {{can only be classes or functions}}
+#else
+ // expected-error@-4 {{use of class template 'T' requires template arguments; argument deduction not allowed in friend declaration}}
+ // expected-note@-7 {{here}}
+#endif
// FIXME: It's not clear whether the standard allows this or what it means,
// but the DR585 writeup suggests it as an alternative.
template<typename U> friend T<U>; // expected-error {{must use an elaborated type}}
};
template<template<typename> class T> struct B {
- friend T; // expected-error {{requires a type specifier}} expected-error {{can only be classes or functions}}
+ friend T;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{requires a type specifier}} expected-error@-2 {{can only be classes or functions}}
+#else
+ // expected-error@-4 {{use of template template parameter 'T' requires template arguments; argument deduction not allowed in friend declaration}}
+ // expected-note@-6 {{here}}
+#endif
template<typename U> friend T<U>; // expected-error {{must use an elaborated type}}
};
}
@@ -942,7 +954,7 @@ namespace dr591 { // dr591: no
template<typename T> struct A<T>::B::C : A<T> {
// FIXME: Should find member of non-dependent base class A<T>.
- M m; // expected-error {{incomplete type 'M' (aka 'void'}}
+ M m; // expected-error {{incomplete type 'dr591::A::B::M' (aka 'void'}}
};
}
diff --git a/test/CXX/expr/expr.post/expr.type.conv/p1.cpp b/test/CXX/expr/expr.post/expr.type.conv/p1.cpp
new file mode 100644
index 000000000000..f3608bc378bc
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.type.conv/p1.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T> struct A { // expected-note 2{{candidate}}
+ T t, u;
+};
+template<typename T> A(T, T) -> A<T>; // expected-note {{deduced conflicting types for parameter 'T'}}
+template<typename T> A(A<T>) -> A<T>; // expected-note {{requires 1 argument, but 2 were provided}}
+
+A a = A{1, 2};
+A b = A{3, 4.0}; // expected-error {{no viable constructor or deduction guide}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
index 4a2a4f3d7353..e7fce11abc5e 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
void odr_used() {
int i = 17;
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
index 8bb707e0dbc7..b55beb7d4ed7 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
void f2() {
int i = 1;
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
index 94f8111015aa..905192ff830b 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
struct X {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
index 93c2805497f3..72cf93be5190 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
// expected-no-diagnostics
template<typename T, typename U>
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 1dbcbf498031..a8b40249f0f0 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
struct MoveOnly {
MoveOnly(MoveOnly&&);
diff --git a/test/CXX/over/over.match/over.match.best/p1.cpp b/test/CXX/over/over.match/over.match.best/p1.cpp
index 59e3dac74283..fad5bf9a72ee 100644
--- a/test/CXX/over/over.match/over.match.best/p1.cpp
+++ b/test/CXX/over/over.match/over.match.best/p1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
// expected-no-diagnostics
template<typename T> int &f0(T*, int);
@@ -12,6 +12,28 @@ void test_f0(int* ip, void *vp) {
float &fr = f0(vp, 0);
}
+namespace deduction_guide_example {
+ template<typename T> struct A {
+ A(T, int*);
+ A(A<T>&, int*);
+ enum { value };
+ };
+
+ template<typename T> struct remove_ref_impl;
+ template<typename T> struct remove_ref_impl<T&> { using type = T; };
+ template<typename T> using remove_ref = typename remove_ref_impl<T>::type;
+
+ // FIXME: The standard's example is wrong; we add a remove_ref<...> here to
+ // fix it.
+ template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T>;
+ A a{1, 0};
+ extern A<int> a;
+ A b{a, 0};
+
+ A<int> *pa = &a;
+ A<A<int>&> *pb = &b;
+}
+
// Partial ordering of function template specializations will be tested
// elsewhere
// FIXME: Initialization by user-defined conversion is tested elsewhere
diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
new file mode 100644
index 000000000000..fe1b6a63d75b
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -verify -std=c++1z %s
+
+namespace Explicit {
+ // Each notional constructor is explicit if the function or function template
+ // was generated from a constructor or deduction-guide that was declared explicit.
+ template<typename T> struct A {
+ A(T);
+ A(T*);
+ };
+ template<typename T> A(T) -> A<T>;
+ template<typename T> explicit A(T*) -> A<T>; // expected-note {{explicit}}
+
+ int *p;
+ A a(p);
+ A b = p;
+ A c{p};
+ A d = {p}; // expected-error {{selected an explicit deduction guide}}
+
+ using X = A<int>;
+ using Y = A<int*>;
+
+ using X = decltype(a);
+ using Y = decltype(b);
+ using X = decltype(c);
+}
diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
new file mode 100644
index 000000000000..4ed1d30b83d5
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+namespace std_example {
+ template <class T> struct A {
+ explicit A(const T &, ...) noexcept; // expected-note {{explicit}} expected-note 2{{candidate}}
+ A(T &&, ...); // expected-note 2{{candidate}}
+ };
+
+ int i;
+ A a1 = {i, i}; // expected-error {{class template argument deduction for 'A' selected an explicit constructor for copy-list-initialization}}
+ A a2{i, i};
+ A a3{0, i};
+ A a4 = {0, i};
+
+ template <class T> A(const T &, const T &) -> A<T &>; // expected-note 2{{candidate}}
+ template <class T> explicit A(T &&, T &&) -> A<T>; // expected-note {{explicit deduction guide declared here}}
+
+ // FIXME: The standard gives an incorrect explanation for why a5, a7, and a8 are ill-formed.
+ A a5 = {0, 1}; // expected-error {{class template argument deduction for 'A' selected an explicit deduction guide}}
+ A a6{0, 1};
+ A a7 = {0, i}; // expected-error {{ambiguous deduction}}
+ A a8{0, i}; // expected-error {{ambiguous deduction}}
+
+ template <class T> struct B {
+ template <class U> using TA = T;
+ template <class U> B(U, TA<U>);
+ };
+ B b{(int *)0, (char *)0};
+}
+
+namespace check {
+ using namespace std_example;
+ template<typename T, typename U> constexpr bool same = false;
+ template<typename T> constexpr bool same<T, T> = true;
+
+ static_assert(same<decltype(a2), A<int>>);
+ static_assert(same<decltype(a3), A<int>>);
+ static_assert(same<decltype(a4), A<int>>);
+ static_assert(same<decltype(a6), A<int>>);
+ static_assert(same<decltype(b), B<char*>>);
+}
diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp
index 3b8a0ad4d6a7..3be0a98d47d7 100644
--- a/test/CXX/special/class.dtor/p10-0x.cpp
+++ b/test/CXX/special/class.dtor/p10-0x.cpp
@@ -33,7 +33,7 @@ void a(const A *x, int i, int *pi) {
expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
pi->~decltype(int())();
- pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+ pi.~decltype(int())(); // expected-error{{member reference type 'int *' is a pointer; did you mean to use '->'?}}
pi.~decltype(intp())();
pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
index 4960a2bac20a..87c22a0d7e94 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
@@ -61,7 +61,7 @@ struct X {
template<class... Members>
template<int i>
-X<Members...>::get_t<i> X<Members...>::get()
+typename X<Members...>::template get_t<i> X<Members...>::get()
{
return 0;
}
diff --git a/test/CXX/temp/temp.deduct.guide/p1.cpp b/test/CXX/temp/temp.deduct.guide/p1.cpp
new file mode 100644
index 000000000000..c0a2ba1129e2
--- /dev/null
+++ b/test/CXX/temp/temp.deduct.guide/p1.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s -DCLASS
+
+#ifdef CLASS
+struct Outer {
+#endif
+
+template<typename> struct A {};
+
+// Valid forms.
+A(int(&)[1]) -> A<int>;
+explicit A(int(&)[2]) -> A<int>;
+
+// Declarator pieces are not OK.
+*A(int(&)[3]) -> A<int>; // expected-error {{cannot specify any part of a return type in the declaration of a deduction guide}}
+&A(int(&)[4]) -> A<int>; // expected-error {{cannot specify any part of a return type in the declaration of a deduction guide}}
+A(int(&)[5])[3] -> A<int>;
+#ifdef CLASS // FIXME: These diagnostics are both pretty bad.
+// expected-error@-2 {{function cannot return array type}} expected-error@-2 {{';'}}
+#else
+// expected-error@-4 {{expected function body after function declarator}}
+#endif
+
+(A[3])(int(&)[5][1]) -> A<int>; // expected-error {{'<deduction guide for A>' cannot be the name of a variable}}
+#ifndef CLASS
+// expected-error@-2 {{declared as array of functions}}
+#endif
+(*A)(int(&)[5][2]) -> A<int>; // expected-error {{'<deduction guide for A>' cannot be the name of a variable}}
+(&A)(int(&)[5][3]) -> A<int>; // expected-error {{'<deduction guide for A>' cannot be the name of a variable}}
+(*A(int))(int(&)[5][4]) -> A<int>; // expected-error {{cannot specify any part of a return type in the declaration of a deduction guide}}
+
+// (Pending DR) attributes and parens around the declarator-id are OK.
+[[deprecated]] A(int(&)[6]) [[]] -> A<int> [[]];
+A [[]] (int(&)[7]) -> A<int>;
+(A)(int(&)[8]) -> A<int>;
+
+// ... but the trailing-return-type is part of the function-declarator as normal
+(A(int(&)[9])) -> A<int>;
+#ifdef CLASS // FIXME: These diagnostics are both pretty bad.
+// expected-error@-2 {{deduction guide declaration without trailing return type}} expected-error@-2 {{';'}}
+#else
+// expected-error@-4 {{expected function body after function declarator}}
+#endif
+(A(int(&)[10]) -> A<int>); // expected-error {{trailing return type may not be nested within parentheses}}
+
+// A trailing-return-type is mandatory.
+A(int(&)[11]); // expected-error {{deduction guide declaration without trailing return type}}
+
+// No type specifier is permitted; we don't even parse such cases as a deduction-guide.
+int A(int) -> A<int>; // expected-error {{function with trailing return type must specify return type 'auto', not 'int'}}
+template<typename T> struct B {}; // expected-note {{here}}
+auto B(int) -> B<int>; // expected-error {{redefinition of 'B' as different kind of symbol}}
+
+// No storage class specifier, function specifier, ...
+friend A(int(&)[20]) -> A<int>;
+#ifdef CLASS
+// expected-error@-2 {{cannot declare a deduction guide as a friend}}
+#else
+// expected-error@-4 {{'friend' used outside of class}}
+#endif
+typedef A(int(&)[21]) -> A<int>; // expected-error {{deduction guide cannot be declared 'typedef'}}
+constexpr A(int(&)[22]) -> A<int>; // expected-error {{deduction guide cannot be declared 'constexpr'}}
+inline A(int(&)[23]) -> A<int>; // expected-error {{deduction guide cannot be declared 'inline'}}
+static A(int(&)[24]) -> A<int>; // expected-error {{deduction guide cannot be declared 'static'}}
+thread_local A(int(&)[25]) -> A<int>; // expected-error {{'thread_local' is only allowed on variable declarations}}
+extern A(int(&)[26]) -> A<int>;
+#ifdef CLASS
+// expected-error@-2 {{storage class specified for a member}}
+#else
+// expected-error@-4 {{deduction guide cannot be declared 'extern'}}
+#endif
+mutable A(int(&)[27]) -> A<int>; // expected-error-re {{{{'mutable' cannot be applied to|illegal storage class on}} function}}
+virtual A(int(&)[28]) -> A<int>; // expected-error {{'virtual' can only appear on non-static member functions}}
+const A(int(&)[28]) -> A<int>; // expected-error {{deduction guide cannot be declared 'const'}}
+
+const volatile static constexpr inline A(int(&)[29]) -> A<int>; // expected-error {{deduction guide cannot be declared 'static inline constexpr const volatile'}}
+
+A(int(&)[30]) const -> A<int>; // expected-error {{deduction guide cannot have 'const' qualifier}}
+
+// No definition is allowed.
+A(int(&)[40]) -> A<int> {} // expected-error {{deduction guide cannot have a function definition}}
+A(int(&)[41]) -> A<int> = default; // expected-error {{deduction guide cannot have a function definition}} expected-error {{only special member functions may be defaulted}}
+A(int(&)[42]) -> A<int> = delete; // expected-error {{deduction guide cannot have a function definition}}
+A(int(&)[43]) -> A<int> try {} catch (...) {} // expected-error {{deduction guide cannot have a function definition}}
+
+#ifdef CLASS
+};
+#endif
+
+namespace ExplicitInst {
+ // Explicit instantiation / specialization is not permitted.
+ template<typename T> struct B {};
+ template<typename T> B(T) -> B<T>;
+ template<> B(int) -> B<int>; // expected-error {{deduction guide cannot be explicitly specialized}}
+ extern template B(float) -> B<float>; // expected-error {{deduction guide cannot be explicitly instantiated}}
+ template B(char) -> B<char>; // expected-error {{deduction guide cannot be explicitly instantiated}}
+
+ // An attempt at partial specialization doesn't even parse as a deduction-guide.
+ template<typename T> B<T*>(T*) -> B<T*>; // expected-error 1+{{}} expected-note 0+{{}}
+
+ struct X {
+ template<typename T> struct C {};
+ template<typename T> C(T) -> C<T>;
+ template<> C(int) -> C<int>; // expected-error {{explicit specialization of '<deduction guide for C>' in class scope}}
+ extern template C(float) -> C<float>; // expected-error {{expected member name or ';'}}
+ template C(char) -> C<char>; // expected-error {{expected '<' after 'template'}}
+ };
+}
diff --git a/test/CXX/temp/temp.deduct.guide/p2.cpp b/test/CXX/temp/temp.deduct.guide/p2.cpp
new file mode 100644
index 000000000000..3549755ff0f2
--- /dev/null
+++ b/test/CXX/temp/temp.deduct.guide/p2.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+// expected-no-diagnostics
+
+namespace std_example {
+ template<typename T, typename U = int> struct S {
+ T data;
+ };
+ template<typename U> S(U) -> S<typename U::type>;
+
+ struct A {
+ using type = short;
+ operator type();
+ };
+ S x{A()};
+}
diff --git a/test/CXX/temp/temp.deduct.guide/p3.cpp b/test/CXX/temp/temp.deduct.guide/p3.cpp
new file mode 100644
index 000000000000..e12f7b6ef255
--- /dev/null
+++ b/test/CXX/temp/temp.deduct.guide/p3.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+
+// The same restrictions apply to the parameter-declaration-clause of a
+// deduction guide as in a function declaration.
+template<typename T> struct A {};
+A(void) -> A<int>; // ok
+A(void, int) -> A<int>; // expected-error {{'void' must be the first and only parameter if specified}}
+
+// We interpret this as also extending to the validity of redeclarations. It's
+// a bit of a stretch (OK, a lot of a stretch) but it gives desirable answers.
+A() -> A<int>; // ok, redeclaration
+
+A() -> A<int>; // expected-note {{previous}}
+A() -> A<float>; // FIXME: "functions" is a poor term. expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+template<typename T> A(T) -> A<typename T::foo>;
+template<typename T> A(T) -> A<typename T::bar>; // ok, can overload on return type (SFINAE applies)
+
+A(long) -> A<int>;
+template<typename T = int> A(long) -> A<char>; // ok, non-template beats template as usual
+
+// (Pending DR) The template-name shall name a class template.
+template<typename T> using B = A<T>; // expected-note {{template}}
+B() -> B<int>; // expected-error {{cannot specify deduction guide for alias template 'B'}}
+// FIXME: expected-error@-1 {{declarator requires an identifier}}
+template<typename T> int C;
+C() -> int; // expected-error {{requires a type specifier}}
+template<typename T> void D();
+D() -> int; // expected-error {{requires a type specifier}}
+template<template<typename> typename TT> struct E { // expected-note 2{{template}}
+ // FIXME: Should only diagnose this once!
+ TT(int) -> TT<int>; // expected-error 2{{cannot specify deduction guide for template template parameter 'TT'}} expected-error {{requires an identifier}}
+};
+
+A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}}
+template<typename T> A(T) -> B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<type-parameter-0-0>') of deduction guide is not written as a specialization of template 'A'}}
+template<typename T> A(T*) -> const A<T>; // expected-error {{deduced type 'const A<T>' of deduction guide is not a specialization of template 'A'}}
+
+// A deduction-guide shall be declared in the same scope as the corresponding
+// class template.
+namespace WrongScope {
+ namespace {
+ template<typename T> struct AnonNS1 {}; // expected-note {{here}}
+ AnonNS1(float) -> AnonNS1<float>; // ok
+ }
+ AnonNS1(int) -> AnonNS1<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::}}
+ template<typename T> struct AnonNS2 {}; // expected-note {{here}}
+ namespace {
+ AnonNS1(char) -> AnonNS1<char>; // ok
+ AnonNS2(int) -> AnonNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::AnonNS2'}}
+ }
+ namespace N {
+ template<typename T> struct NamedNS1 {}; // expected-note {{here}}
+ template<typename T> struct NamedNS2 {}; // expected-note {{here}}
+ }
+ using N::NamedNS1;
+ NamedNS1(int) -> NamedNS1<int>; // expected-error {{deduction guide must be declared in the same scope as template}}
+ using namespace N;
+ NamedNS2(int) -> NamedNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template}}
+ struct ClassMemberA {
+ template<typename T> struct X {}; // expected-note {{here}}
+ };
+ struct ClassMemberB : ClassMemberA {
+ X(int) -> X<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::ClassMemberA::X'}}
+ };
+ template<typename T> struct Local {};
+ void f() {
+ Local(int) -> Local<int>; // expected-error 2{{expected}} expected-note {{to match}}
+ using WrongScope::Local;
+ Local(int) -> Local<int>; // expected-error 2{{expected}} expected-note {{to match}}
+ }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
index e470dd016644..ebff0a1df4e7 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
@@ -1,9 +1,39 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s
+// A forwarding reference is an rvalue reference to a cv-unqualified template
+// parameter that does not represent a template parameter of a class template.
+#if __cplusplus > 201402L
+namespace ClassTemplateParamNotForwardingRef {
+ // This is not a forwarding reference.
+ template<typename T> struct A { // expected-note {{candidate}}
+ A(T&&); // expected-note {{no known conversion from 'int' to 'int &&'}}
+ };
+ int n;
+ A a = n; // expected-error {{no viable constructor or deduction guide}}
-// If P is an rvalue reference to a cv-unqualified template parameter
-// and the argument is an lvalue, the type "lvalue reference to A" is
-// used in place of A for type deduction.
+ A b = 0;
+ A<int> *pb = &b;
+
+ // This is a forwarding reference.
+ template<typename T> A(T&&) -> A<T>;
+ A c = n;
+ A<int&> *pc = &c;
+
+ A d = 0;
+ A<int> *pd = &d;
+
+ template<typename T = void> struct B {
+ // This is a forwarding reference.
+ template<typename U> B(U &&);
+ };
+ B e = n;
+ B<void> *pe = &e;
+}
+#endif
+
+// If P is a forwarding reference and the argument is an lvalue, the type
+// "lvalue reference to A" is used in place of A for type deduction.
template<typename T> struct X { };
template<typename T> X<T> f0(T&&);
@@ -43,4 +73,21 @@ namespace std_example {
int n1 = f(i);
int n2 = f(0);
int n3 = g(i); // expected-error{{no matching function for call to 'g'}}
+
+#if __cplusplus > 201402L
+ template<class T> struct A { // expected-note {{candidate}}
+ template<class U>
+ A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: no known conversion from 'int' to 'int &&'}}
+ A(T &&, int *); // expected-note {{requires 2}}
+ };
+ template<class T> A(T &&, int *) -> A<T>; // expected-note {{requires 2}}
+
+ int *ip;
+ A a{i, 0, ip}; // expected-error {{no viable constructor or deduction guide}}
+ A a0{0, 0, ip};
+ A a2{i, ip};
+
+ A<int> &a0r = a0;
+ A<int&> &a2r = a2;
+#endif
}
diff --git a/test/CXX/temp/temp.res/p3.cpp b/test/CXX/temp/temp.res/p3.cpp
new file mode 100644
index 000000000000..ea87b8d10546
--- /dev/null
+++ b/test/CXX/temp/temp.res/p3.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify %s -std=c++11
+
+template<typename T> struct A {
+ template<typename U> struct B;
+ template<typename U> using C = U; // expected-note {{here}}
+};
+
+struct X {
+ template<typename T> X(T);
+ struct Y {
+ template<typename T> Y(T);
+ };
+};
+
+template<typename T> A // expected-error {{missing 'typename' prior to dependent type template name 'A<T>::B'}}
+ <T>::B<T> f1();
+template<typename T> A<T>::C<T> f2(); // expected-error {{missing 'typename' prior to dependent type template name 'A<T>::C'}}
+
+// FIXME: Should these cases really be valid? There doesn't appear to be a rule prohibiting them...
+template<typename T> A<T>::C<X>::X(T) {}
+template<typename T> A<T>::C<X>::X::Y::Y(T) {}
+
+// FIXME: This is ill-formed
+template<typename T> int A<T>::B<T>::*f3() {}
+template<typename T> int A<T>::C<X>::*f4() {}
+
+// FIXME: This is valid
+template<typename T> int A<T>::template C<int>::*f5() {} // expected-error {{has no members}}
+
+template<typename T> template<typename U> struct A<T>::B {
+ friend A<T>::C<T> f6(); // ok, same as 'friend T f6();'
+
+ // FIXME: Error recovery here is awful; we decide that the template-id names
+ // a type, and then complain about the rest of the tokens, and then complain
+ // that we didn't get a function declaration.
+ friend A<U>::C<T> f7(); // expected-error {{use 'template' keyword to treat 'C' as a dependent template name}} expected-error 3{{}}
+ friend A<U>::template C<T> f8(); // expected-error 3{{}}
+};
diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp
index f6ef636daa56..faa85cb5fce3 100644
--- a/test/CXX/temp/temp.res/temp.local/p1.cpp
+++ b/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -1,12 +1,55 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
-// C++0x [temp.local]p1:
+// C++1z [temp.local]p1:
// Like normal (non-template) classes, class templates have an
-// injected-class-name (Clause 9). The injected-class-name can be used with
-// or without a template-argument-list. When it is used without
-// a template-argument-list, it is equivalent to the injected-class-name
-// followed by the template-parameters of the class template enclosed in <>.
+// injected-class-name (Clause 9). The injected-class-name can
+// be used as a template-name or a type-name.
+
+template<typename> char id;
+
+template<typename> struct TempType {};
+template<template<typename> class> struct TempTemp {};
+
+template<typename> void use(int&); // expected-note {{invalid explicitly-specified argument}} expected-note {{no known conversion}}
+template<template<typename> class> void use(float&); // expected-note 2{{no known conversion}}
+template<int> void use(char&); // expected-note 2{{invalid explicitly-specified argument}}
+
+template<typename T> struct A {
+ template<typename> struct C {};
+ struct B : C<T> {
+ // When it is used with a template-argument-list,
+ A<int> *aint;
+ typename B::template C<int> *cint;
+
+ // as a template-argument for a template template-parameter,
+ TempTemp<A> a_as_temp;
+ TempTemp<B::template C> c_as_temp;
+
+ // or as the final identifier in the elaborated-type-specifier of a friend
+ // class template declaration,
+ template<typename U> friend struct A;
+ // it refers to the class template itself.
+
+ // Otherwise, it is equivalent to the template-name followed by the
+ // template-parameters of the class template enclosed in <>.
+ A *aT;
+ typename B::C *cT;
+ TempType<A> a_as_type;
+ TempType<typename B::C> c_as_type;
+ friend struct A;
+ friend struct B::C;
+
+ void f(T &t) {
+ use<A>(t); // expected-error {{no matching function}}
+ if constexpr (&id<T> != &id<int>)
+ use<B::template C>(t); // expected-error {{no matching function}}
+ }
+ };
+};
+
+template struct A<int>;
+template struct A<float>;
+template struct A<char>; // expected-note {{instantiation of}}
template <typename T> struct X0 {
X0();
diff --git a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
index 7eb5e3744d18..425d527e5212 100644
--- a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
+++ b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
@@ -9,7 +9,7 @@ T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
template int pi<int>;
#ifndef FIXING
-template float pi<>; // expected-error {{too few template arguments for template 'pi'}}
+template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}}
template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
#endif