summaryrefslogtreecommitdiffstats
path: root/test/CXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.link/p6.cpp43
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp92
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp30
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp2
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2.cpp101
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2a.cpp9
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2b.cpp9
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2c.cpp5
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2d.cpp4
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2e.cpp4
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2f.cpp7
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2g.cpp5
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2h.cpp5
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2i.cpp6
-rw-r--r--test/CXX/basic/basic.types/p10.cpp2
-rw-r--r--test/CXX/class.access/class.access.base/p5.cpp23
-rw-r--r--test/CXX/class.access/class.friend/p3-cxx0x.cpp7
-rw-r--r--test/CXX/class.access/class.protected/p1.cpp7
-rw-r--r--test/CXX/class.derived/class.abstract/p16.cpp26
-rw-r--r--test/CXX/class.derived/class.virtual/p3-0x.cpp30
-rw-r--r--test/CXX/class/class.static/class.static.data/p3.cpp2
-rw-r--r--test/CXX/class/class.union/p1.cpp59
-rw-r--r--test/CXX/class/class.union/p2-0x.cpp2
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp101
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp9
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp74
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.align/p6.cpp86
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp16
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp6
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp32
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp14
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp44
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp3
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp3
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp22
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp22
-rw-r--r--test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp25
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp33
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp8
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp14
-rw-r--r--test/CXX/dcl.decl/dcl.init/p5.cpp48
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp5
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp6
-rw-r--r--test/CXX/except/except.spec/p14-ir.cpp12
-rw-r--r--test/CXX/except/except.spec/p14.cpp11
-rw-r--r--test/CXX/except/except.spec/p9-noexcept.cpp7
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp13
-rw-r--r--test/CXX/expr/expr.post/expr.call/p7-0x.cpp15
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp37
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp3
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp5
-rw-r--r--test/CXX/lex/lex.literal/lex.ext/p5.cpp7
-rw-r--r--test/CXX/lex/lex.pptoken/p3-0x.cpp4
-rw-r--r--test/CXX/over/over.oper/over.literal/p8.cpp3
-rw-r--r--test/CXX/special/class.copy/implicit-move.cpp2
-rw-r--r--test/CXX/special/class.copy/p12-0x.cpp216
-rw-r--r--test/CXX/special/class.copy/p18-cxx11.cpp62
-rw-r--r--test/CXX/special/class.copy/p23-cxx11.cpp2
-rw-r--r--test/CXX/special/class.copy/p25-0x.cpp202
-rw-r--r--test/CXX/special/class.copy/p28-cxx11.cpp19
-rw-r--r--test/CXX/special/class.ctor/p1.cpp14
-rw-r--r--test/CXX/special/class.ctor/p5-0x.cpp47
-rw-r--r--test/CXX/special/class.dtor/p3-0x.cpp6
-rw-r--r--test/CXX/special/class.dtor/p5-0x.cpp5
-rw-r--r--test/CXX/special/class.inhctor/elsewhere.cpp20
-rw-r--r--test/CXX/special/class.inhctor/p1.cpp31
-rw-r--r--test/CXX/special/class.inhctor/p2.cpp87
-rw-r--r--test/CXX/special/class.inhctor/p3.cpp12
-rw-r--r--test/CXX/special/class.inhctor/p4.cpp70
-rw-r--r--test/CXX/special/class.inhctor/p7.cpp12
-rw-r--r--test/CXX/special/class.inhctor/p8.cpp21
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p5.cpp9
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p5.mm9
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp21
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp21
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp3
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp13
-rw-r--r--test/CXX/temp/temp.res/temp.dep/p3.cpp47
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp5
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp2
82 files changed, 1945 insertions, 187 deletions
diff --git a/test/CXX/basic/basic.link/p6.cpp b/test/CXX/basic/basic.link/p6.cpp
new file mode 100644
index 0000000..8faec76
--- /dev/null
+++ b/test/CXX/basic/basic.link/p6.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++11 [basic.link]p6:
+// The name of a function declared in block scope and the name
+// of a variable declared by a block scope extern declaration
+// have linkage. If there is a visible declaration of an entity
+// with linkage having the same name and type, ignoring entities
+// declared outside the innermost enclosing namespace scope, the
+// block scope declaration declares that same entity and
+// receives the linkage of the previous declaration.
+
+// rdar://13535367
+namespace test0 {
+ extern "C" int test0_array[];
+ void declare() { extern int test0_array[100]; }
+ extern "C" int test0_array[];
+ int value = sizeof(test0_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+}
+
+namespace test1 {
+ extern "C" int test1_array[];
+ void test() {
+ { extern int test1_array[100]; }
+ extern int test1_array[];
+ int x = sizeof(test1_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+ }
+}
+
+namespace test2 {
+ void declare() { extern int test2_array[100]; }
+ extern int test2_array[];
+ int value = sizeof(test2_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+}
+
+namespace test3 {
+ void test() {
+ { extern int test3_array[100]; }
+ extern int test3_array[];
+ int x = sizeof(test3_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
+ }
+}
+
+
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 7ecedd5..1f78a73 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,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 X0 {
X0 f1();
X0 f2();
@@ -25,3 +26,92 @@ 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> struct X1<T>::X1<T> (X1<T>::f2)(float) { }
+
+// We have a special case for lookup within using-declarations that are
+// member-declarations: foo::bar::baz::baz always names baz's constructor
+// in such a context, even if looking up 'baz' within foo::bar::baz would
+// not find the injected-class-name. Likewise foo::bar::baz<T>::baz also
+// names the constructor.
+namespace InhCtor {
+ struct A {
+ A(int);
+ protected:
+ int T();
+ };
+ typedef A T;
+ struct B : A {
+ // This is a using-declaration for 'int A::T()' in C++98, but is an
+ // inheriting constructor declaration in C++11.
+ using InhCtor::T::T;
+ };
+#if __cplusplus < 201103L
+ B b(123); // expected-error {{no matching constructor}}
+ // expected-note@-7 2{{candidate constructor}}
+ int n = b.T(); // ok, accessible
+#else
+ B b(123); // ok, inheriting constructor
+ int n = b.T(); // expected-error {{'T' is a protected member of 'InhCtor::A'}}
+ // expected-note@-15 {{declared protected here}}
+
+ template<typename T>
+ struct S : T {
+ struct U : S {
+ using S::S;
+ };
+ using T::T;
+ };
+
+ S<A>::U ua(0);
+ S<B>::U ub(0);
+
+ template<typename T>
+ struct X : T {
+ using T::Z::U::U;
+ };
+ template<typename T>
+ struct X2 : T {
+ using T::Z::template V<int>::V;
+ };
+ struct Y {
+ struct Z {
+ typedef Y U;
+ template<typename T> using V = Y;
+ };
+ Y(int);
+ };
+ X<Y> xy(0);
+
+ namespace Repeat {
+ struct A {
+ struct T {
+ T(int);
+ };
+ };
+ struct Z : A {
+ using A::A::A;
+ };
+ template<typename T>
+ struct ZT : T::T {
+ using T::T::T;
+ };
+ }
+
+ namespace NS {
+ struct NS {};
+ }
+ struct DerivedFromNS : NS::NS {
+ // No special case unless the NNS names a class.
+ using InhCtor::NS::NS; // expected-error {{using declaration in class refers into 'InhCtor::NS::', which is not a class}}
+
+ };
+
+ typedef int I;
+ struct UsingInt {
+ using I::I; // expected-error {{expected a class or namespace}}
+ };
+ template<typename T> struct UsingIntTemplate {
+ using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+ };
+ UsingIntTemplate<int> uit; // expected-note {{here}}
+#endif
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
index 4ffe538..7da3087 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
@@ -17,3 +17,33 @@ namespace N {
int i = 2;
N::S N::j = i;
N::S N::j2(i);
+
+// <rdar://problem/13317030>
+namespace M {
+ class X { };
+ inline X operator-(int, X);
+
+ template<typename T>
+ class Y { };
+
+ typedef Y<float> YFloat;
+
+ namespace yfloat {
+ YFloat operator-(YFloat, YFloat);
+ }
+ using namespace yfloat;
+}
+
+using namespace M;
+
+namespace M {
+
+class Other {
+ void foo(YFloat a, YFloat b);
+};
+
+}
+
+void Other::foo(YFloat a, YFloat b) {
+ YFloat c = a - b;
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
index d2afd5d..9632fda 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
@@ -33,5 +33,5 @@ namespace test1 {
// specifiers.
namespace test2 {
template <class T> struct bar {};
- template <class T> struct foo : bar<foo> {}; // expected-error {{use of class template foo requires template arguments}} expected-note {{template is declared here}}
+ template <class T> struct foo : bar<foo> {}; // expected-error {{use of class template 'foo' requires template arguments}} expected-note {{template is declared here}}
}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2.cpp b/test/CXX/basic/basic.start/basic.start.main/p2.cpp
new file mode 100644
index 0000000..a5386f1
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST1
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST2
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST3
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST4
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST5
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST6
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST7
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST8
+
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x c++ %s -std=c++11 -fsyntax-only -verify -DTEST9
+// RUN: not %clang_cc1 -x c++ %t -std=c++11 -fixit -DTEST9
+// RUN: %clang_cc1 -x c++ %t -std=c++11 -fsyntax-only -DTEST9
+
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST10
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST12
+
+#if TEST1
+
+// expected-no-diagnostics
+typedef int Int;
+typedef char Char;
+typedef Char* Carp;
+
+Int main(Int argc, Carp argv[]) {
+}
+
+#elif TEST2
+
+// expected-no-diagnostics
+typedef int Int;
+typedef char Char;
+typedef Char* Carp;
+
+Int main(Int argc, Carp argv[], Char *env[]) {
+}
+
+#elif TEST3
+
+// expected-no-diagnostics
+int main() {
+}
+
+#elif TEST4
+
+static int main() { // expected-error {{'main' is not allowed to be declared static}}
+}
+
+#elif TEST5
+
+inline int main() { // expected-error {{'main' is not allowed to be declared inline}}
+}
+
+#elif TEST6
+
+void // expected-error {{'main' must return 'int'}}
+main( // expected-error {{first parameter of 'main' (argument count) must be of type 'int'}}
+ float a
+) {
+}
+
+#elif TEST7
+
+// expected-no-diagnostics
+int main(int argc, const char* const* argv) {
+}
+
+#elif TEST8
+
+template<typename T>
+int main() { } // expected-error{{'main' cannot be a template}}
+
+#elif TEST9
+
+constexpr int main() { } // expected-error{{'main' is not allowed to be declared constexpr}}
+
+#elif TEST10
+
+// PR15100
+// expected-no-diagnostics
+typedef char charT;
+int main(int, const charT**) {}
+
+#elif TEST11
+
+// expected-no-diagnostics
+typedef char charT;
+int main(int, charT* const *) {}
+
+#elif TEST12
+
+// expected-no-diagnostics
+typedef char charT;
+int main(int, const charT* const *) {}
+
+#else
+
+#error Unknown test mode
+
+#endif
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2a.cpp b/test/CXX/basic/basic.start/basic.start.main/p2a.cpp
deleted file mode 100644
index b27d492..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2a.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-typedef int Int;
-typedef char Char;
-typedef Char* Carp;
-
-Int main(Int argc, Carp argv[]) {
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2b.cpp b/test/CXX/basic/basic.start/basic.start.main/p2b.cpp
deleted file mode 100644
index 65cd202..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2b.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-typedef int Int;
-typedef char Char;
-typedef Char* Carp;
-
-Int main(Int argc, Carp argv[], Char *env[]) {
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2c.cpp b/test/CXX/basic/basic.start/basic.start.main/p2c.cpp
deleted file mode 100644
index 2b082ec..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2c.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-int main() {
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2d.cpp b/test/CXX/basic/basic.start/basic.start.main/p2d.cpp
deleted file mode 100644
index bcdbdb2..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2d.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-static int main() { // expected-error {{'main' is not allowed to be declared static}}
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2e.cpp b/test/CXX/basic/basic.start/basic.start.main/p2e.cpp
deleted file mode 100644
index 954fdbd..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2e.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-inline int main() { // expected-error {{'main' is not allowed to be declared inline}}
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2f.cpp b/test/CXX/basic/basic.start/basic.start.main/p2f.cpp
deleted file mode 100644
index ea5a752..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2f.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-void // expected-error {{'main' must return 'int'}}
-main( // expected-error {{first parameter of 'main' (argument count) must be of type 'int'}}
- float a
-) {
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2g.cpp b/test/CXX/basic/basic.start/basic.start.main/p2g.cpp
deleted file mode 100644
index 45f643f..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2g.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-int main(int argc, const char* const* argv) {
-}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2h.cpp b/test/CXX/basic/basic.start/basic.start.main/p2h.cpp
deleted file mode 100644
index abf8faa..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2h.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-template<typename T>
-int main() { } // expected-error{{'main' cannot be a template}}
-
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2i.cpp b/test/CXX/basic/basic.start/basic.start.main/p2i.cpp
deleted file mode 100644
index db8da3c..0000000
--- a/test/CXX/basic/basic.start/basic.start.main/p2i.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: cp %s %t
-// RUN: %clang_cc1 -x c++ %s -std=c++11 -fsyntax-only -verify
-// RUN: not %clang_cc1 -x c++ %t -std=c++11 -fixit
-// RUN: %clang_cc1 -x c++ %t -std=c++11 -fsyntax-only
-
-constexpr int main() { } // expected-error{{'main' is not allowed to be declared constexpr}}
diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp
index 191d42b..6401c29 100644
--- a/test/CXX/basic/basic.types/p10.cpp
+++ b/test/CXX/basic/basic.types/p10.cpp
@@ -39,7 +39,7 @@ struct UserProvDtor {
struct NonTrivDtor {
constexpr NonTrivDtor();
constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
- virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}}
+ virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} expected-note {{because it is virtual}}
};
struct NonTrivDtorBase {
~NonTrivDtorBase();
diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp
index 255fbfc..5b08a86 100644
--- a/test/CXX/class.access/class.access.base/p5.cpp
+++ b/test/CXX/class.access/class.access.base/p5.cpp
@@ -72,4 +72,27 @@ namespace test3 {
};
}
+// Don't crash. <rdar://12926092>
+// Note that 'field' is indeed a private member of X but that access
+// is indeed ultimately constrained by the protected inheritance from Y.
+// If someone wants to put the effort into improving this diagnostic,
+// they can feel free; even explaining it in person would be a pain.
+namespace test4 {
+ class Z;
+ class X {
+ public:
+ void f(Z *p);
+
+ private:
+ int field; // expected-note {{member is declared here}}
+ };
+
+ class Y : public X { };
+ class Z : protected Y { }; // expected-note 2 {{constrained by protected inheritance here}}
+
+ void X::f(Z *p) {
+ p->field = 0; // expected-error {{cannot cast 'test4::Z' to its protected base class 'test4::X'}} expected-error {{'field' is a private member of 'test4::X'}}
+ }
+}
+
// TODO: flesh out these cases
diff --git a/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
index e4d5fd5..ea9d2ce 100644
--- a/test/CXX/class.access/class.friend/p3-cxx0x.cpp
+++ b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
@@ -28,14 +28,19 @@ X1<Y2> x1a;
X1<Y3> x1b;
X1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}}
+template<typename T> class B;
+
template<typename T>
class A {
T x;
public:
class foo {};
static int y;
+ template <typename S> friend class B<S>::ty;
};
+template <typename T> class B { typedef int ty; };
+
struct {
// Ill-formed
int friend; // expected-error {{'friend' must appear first in a non-function declaration}}
@@ -53,3 +58,5 @@ struct {
float;
template<typename T> friend class A<T>::foo;
} a;
+
+void testA() { (void)sizeof(A<int>); }
diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp
index 132ff61..825447e 100644
--- a/test/CXX/class.access/class.protected/p1.cpp
+++ b/test/CXX/class.access/class.protected/p1.cpp
@@ -329,7 +329,7 @@ namespace test8 {
namespace test9 {
class A { // expected-note {{member is declared here}}
- protected: int foo(); // expected-note 4 {{declared}} expected-note 2 {{can only access this member on an object of type}} expected-note {{member is declared here}}
+ protected: int foo(); // expected-note 4 {{declared}} expected-note 3 {{can only access this member on an object of type}} expected-note 2 {{member is declared here}}
};
class B : public A { // expected-note {{member is declared here}}
@@ -344,14 +344,15 @@ namespace test9 {
static void test(A &a) {
a.foo(); // expected-error {{'foo' is a protected member}}
a.A::foo(); // expected-error {{'foo' is a protected member}}
- a.B::foo();
+ a.B::foo(); // expected-error {{'foo' is a protected member}}
a.C::foo(); // expected-error {{'foo' is a protected member}}
+ a.D::foo(); // expected-error {{'foo' is a protected member}}
}
static void test(B &b) {
b.foo();
b.A::foo();
- b.B::foo();
+ b.B::foo(); // accessible as named in A
b.C::foo(); // expected-error {{'foo' is a protected member}}
}
diff --git a/test/CXX/class.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp
index 93f905c..c237ed9 100644
--- a/test/CXX/class.derived/class.abstract/p16.cpp
+++ b/test/CXX/class.derived/class.abstract/p16.cpp
@@ -14,3 +14,29 @@ struct C: A {
virtual void a();
virtual void b() = delete;
};
+
+struct E;
+struct F;
+struct G;
+struct H;
+struct D {
+ virtual E &operator=(const E &); // expected-note {{here}}
+ virtual F &operator=(const F &);
+ virtual G &operator=(G&&);
+ virtual H &operator=(H&&); // expected-note {{here}}
+ friend struct F;
+
+private:
+ D &operator=(const D&) = default;
+ 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 F : D {};
+// No move ctor here, because it would be deleted.
+struct G : D {}; // expected-error {{deleted function '~G' cannot override a non-deleted function}}
+struct H : D {
+ H &operator=(H&&) = default; // expected-error {{deleted function 'operator=' cannot override a non-deleted function}}
+ ~H();
+};
diff --git a/test/CXX/class.derived/class.virtual/p3-0x.cpp b/test/CXX/class.derived/class.virtual/p3-0x.cpp
index 16f9828..6a02a86 100644
--- a/test/CXX/class.derived/class.virtual/p3-0x.cpp
+++ b/test/CXX/class.derived/class.virtual/p3-0x.cpp
@@ -100,3 +100,33 @@ namespace PR13499 {
Y<X> y;
Z<X> z; // expected-note {{in instantiation of}}
}
+
+namespace MemberOfUnknownSpecialization {
+ template<typename T> struct A {
+ struct B {};
+ struct C : B {
+ void f() override;
+ };
+ };
+
+ template<> struct A<int>::B {
+ virtual void f();
+ };
+ // ok
+ A<int>::C c1;
+
+ template<> struct A<char>::B {
+ void f();
+ };
+ // expected-error@-13 {{only virtual member functions can be marked 'override'}}
+ // expected-note@+1 {{in instantiation of}}
+ A<char>::C c2;
+
+ template<> struct A<double>::B {
+ virtual void f() final;
+ };
+ // expected-error@-20 {{declaration of 'f' overrides a 'final' function}}
+ // expected-note@-3 {{here}}
+ // expected-note@+1 {{in instantiation of}}
+ A<double>::C c3;
+}
diff --git a/test/CXX/class/class.static/class.static.data/p3.cpp b/test/CXX/class/class.static/class.static.data/p3.cpp
index 117997e..1607bac 100644
--- a/test/CXX/class/class.static/class.static.data/p3.cpp
+++ b/test/CXX/class/class.static/class.static.data/p3.cpp
@@ -13,7 +13,7 @@ struct S {
static const int d2 = 0;
static constexpr double e = 0.0; // ok
- static const double f = 0.0; // expected-warning {{extension}} expected-note {{use 'constexpr' specifier}}
+ static const double f = 0.0; // expected-error {{requires 'constexpr' specifier}} expected-note {{add 'constexpr'}}
static char *const g = 0; // expected-error {{requires 'constexpr' specifier}}
static const NonLit h = NonLit(); // expected-error {{must be initialized out of line}}
};
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
index ee97410..439cc9c 100644
--- a/test/CXX/class/class.union/p1.cpp
+++ b/test/CXX/class/class.union/p1.cpp
@@ -14,25 +14,25 @@ class VirtualBase : virtual Okay { // expected-note 4 {{because type 'VirtualBas
};
class Ctor {
- Ctor() { abort(); } // expected-note 4 {{because type 'Ctor' has a user-declared constructor}}
+ Ctor() { abort(); } // expected-note 2{{because type 'Ctor' has a user-provided default constructor}} expected-note 2{{here}}
};
class Ctor2 {
- Ctor2(); // expected-note 3 {{because type 'Ctor2' has a user-declared constructor}}
+ Ctor2(); // expected-note {{because type 'Ctor2' has a user-provided default constructor}} expected-note 2{{here}}
};
-class CtorTmpl {
- template<typename T> CtorTmpl(); // expected-note {{because type 'CtorTmpl' has a user-declared constructor}}
+class CtorTmpl { // expected-note {{because type 'CtorTmpl' has no default constructor}}
+ template<typename T> CtorTmpl(); // expected-note {{implicit default constructor suppressed by user-declared constructor}}
};
-class CopyCtor {
- CopyCtor(CopyCtor &cc) { abort(); } // expected-note 4 {{because type 'CopyCtor' has a user-declared copy constructor}}
+class CopyCtor { // expected-note 2{{because no constructor can be used to copy an object of type 'const CopyCtor'}}
+ CopyCtor(CopyCtor &cc) { abort(); }
};
-class CopyAssign {
- CopyAssign& operator=(CopyAssign& CA) { abort(); } // expected-note 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}}
+class CopyAssign { // expected-note 2 {{because no assignment operator can be used to copy an object of type 'const CopyAssign'}}
+ CopyAssign& operator=(CopyAssign& CA) { abort(); }
};
class Dtor {
- ~Dtor() { abort(); } // expected-note 4 {{because type 'Dtor' has a user-declared destructor}}
+ ~Dtor() { abort(); } // expected-note 2 {{because type 'Dtor' has a user-provided destructor}} expected-note 2{{here}}
};
union U1 {
@@ -49,25 +49,25 @@ union U1 {
union U2 {
struct {
- Virtual v; // expected-note {{because type 'U2::<anonymous struct}}
+ Virtual v; // expected-note {{because the function selected to copy field of type 'Virtual' is not trivial}}
} m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
struct {
- VirtualBase vbase; // expected-note {{because type 'U2::<anonymous struct}}
+ VirtualBase vbase; // expected-note {{because the function selected to copy field of type 'VirtualBase' is not trivial}}
} m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
struct {
- Ctor ctor; // expected-note {{because type 'U2::<anonymous struct}}
+ Ctor ctor; // expected-note {{because field of type 'Ctor' has a user-provided default constructor}}
} m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
struct {
- Ctor2 ctor2; // expected-note {{because type 'U2::<anonymous struct}}
+ Ctor2 ctor2; // expected-note {{because field of type 'Ctor2' has a user-provided default constructor}}
} m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
- struct {
- CopyCtor copyctor; // expected-note {{because type 'U2::<anonymous struct}}
+ struct { // expected-note {{no constructor can be used to copy an object of type 'const}}
+ CopyCtor copyctor;
} m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
- struct {
- CopyAssign copyassign; // expected-note {{because type 'U2::<anonymous struct}}
+ struct { // expected-note {{no assignment operator can be used to copy an object of type 'const}}
+ CopyAssign copyassign;
} m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
struct {
- Dtor dtor; // expected-note {{because type 'U2::<anonymous struct}}
+ Dtor dtor; // expected-note {{because field of type 'Dtor' has a user-provided destructor}}
} m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
struct {
Okay okay;
@@ -75,22 +75,25 @@ union U2 {
};
union U3 {
- struct s1 : Virtual { // expected-note {{because type 'U3::s1' has a base class with a non-trivial copy constructor}}
+ struct s1 : Virtual { // expected-note {{because the function selected to copy base class of type 'Virtual' is not trivial}}
} m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
- struct s2 : VirtualBase { // expected-note {{because type 'U3::s2' has a base class with a non-trivial copy constructor}}
+ struct s2 : VirtualBase { // expected-note {{because the function selected to copy base class of type 'VirtualBase' is not trivial}}
} m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
- struct s3 : Ctor { // expected-note {{because type 'U3::s3' has a base class with a non-trivial constructor}}
+ struct s3 : Ctor { // expected-note {{because base class of type 'Ctor' has a user-provided default constructor}}
} m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
- struct s3a : Ctor2 { // expected-note {{because type 'U3::s3a' has a base class with a non-trivial constructor}}
+ struct s3a : Ctor2 { // expected-note {{because base class of type 'Ctor2' has a user-provided default constructor}}
} m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
- struct s4 : CopyCtor { // expected-note {{because type 'U3::s4' has a base class with a non-trivial copy constructor}}
+ struct s4 : CopyCtor { // expected-note {{because no constructor can be used to copy an object of type 'const U3::s4'}}
} m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
- struct s5 : CopyAssign { // expected-note {{because type 'U3::s5' has a base class with a non-trivial copy assignment operator}}
+ struct s5 : CopyAssign { // expected-note {{because no assignment operator can be used to copy an object of type 'const U3::s5'}}
} m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
- struct s6 : Dtor { // expected-note {{because type 'U3::s6' has a base class with a non-trivial destructor}}
+ struct s6 : Dtor { // expected-note {{because base class of type 'Dtor' has a user-provided destructor}}
} m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
struct s7 : Okay {
} m7;
+ struct s8 {
+ s8(...) = delete; // expected-note {{because it is a variadic function}} expected-warning {{C++11}}
+ } m8; // expected-error {{union member 'm8' has a non-trivial constructor}}
};
union U4 {
@@ -102,6 +105,12 @@ union U5 {
int& i1; // expected-error {{union member 'i1' has reference type 'int &'}}
};
+union U6 {
+ struct S {
+ int &i;
+ } s; // ok
+};
+
template <class A, class B> struct Either {
bool tag;
union { // expected-note 6 {{in instantiation of member class}}
diff --git a/test/CXX/class/class.union/p2-0x.cpp b/test/CXX/class/class.union/p2-0x.cpp
index b5c4109..5fb8a67 100644
--- a/test/CXX/class/class.union/p2-0x.cpp
+++ b/test/CXX/class/class.union/p2-0x.cpp
@@ -7,7 +7,7 @@ union U1 {
static const int k2 = k1;
static int k3 = k2; // expected-error {{non-const static data member must be initialized out of line}}
static constexpr double k4 = k2;
- static const double k5 = k4; // expected-warning {{GNU extension}} expected-note {{use 'constexpr'}}
+ static const double k5 = k4; // expected-error {{requires 'constexpr' specifier}} expected-note {{add 'constexpr'}}
int n[k1 + 3];
};
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
index 069ca0a..11372dd 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
@@ -91,3 +91,104 @@ namespace test5 {
template void f<int>(int);
template void f<long>(long); //expected-note {{instantiation}}
}
+
+// rdar://13393749
+namespace test6 {
+ class A;
+ namespace ns {
+ class B {
+ static void foo(); // expected-note {{implicitly declared private here}}
+ friend union A;
+ };
+
+ union A {
+ void test() {
+ B::foo();
+ }
+ };
+ }
+
+ class A {
+ void test() {
+ ns::B::foo(); // expected-error {{'foo' is a private member of 'test6::ns::B'}}
+ }
+ };
+}
+
+// We seem to be following a correct interpretation with these, but
+// the standard could probably be a bit clearer.
+namespace test7a {
+ namespace ns {
+ class A;
+ }
+
+ using namespace ns;
+ class B {
+ static void foo();
+ friend class A;
+ };
+
+ class ns::A {
+ void test() {
+ B::foo();
+ }
+ };
+}
+namespace test7b {
+ namespace ns {
+ class A;
+ }
+
+ using ns::A;
+ class B {
+ static void foo();
+ friend class A;
+ };
+
+ class ns::A {
+ void test() {
+ B::foo();
+ }
+ };
+}
+namespace test7c {
+ namespace ns1 {
+ class A;
+ }
+
+ namespace ns2 {
+ // ns1::A appears as if declared in test7c according to [namespace.udir]p2.
+ // I think that means we aren't supposed to find it.
+ using namespace ns1;
+ class B {
+ static void foo(); // expected-note {{implicitly declared private here}}
+ friend class A;
+ };
+ }
+
+ class ns1::A {
+ void test() {
+ ns2::B::foo(); // expected-error {{'foo' is a private member of 'test7c::ns2::B'}}
+ }
+ };
+}
+namespace test7d {
+ namespace ns1 {
+ class A;
+ }
+
+ namespace ns2 {
+ // Honor the lexical context of a using-declaration, though.
+ using ns1::A;
+ class B {
+ static void foo();
+ friend class A;
+ };
+ }
+
+ class ns1::A {
+ void test() {
+ ns2::B::foo();
+ }
+ };
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
index ae40062..a38ff15 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
@@ -33,3 +33,12 @@ namespace test1 {
}
}
+// PR 14768
+namespace PR14768 {
+ template<typename eT> class Mat;
+ template<typename eT> class Col : public Mat<eT> {
+ using Mat<eT>::operator();
+ using Col<eT>::operator();
+ void operator() ();
+ };
+}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp
new file mode 100644
index 0000000..10be98d
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -verify %s
+
+alignas(1) int n1; // expected-error {{requested alignment is less than minimum alignment of 4 for type 'int'}}
+alignas(1) alignas(2) int n2; // expected-error {{less than minimum alignment}}
+alignas(1) alignas(2) alignas(4) int n3; // ok
+alignas(1) alignas(2) alignas(0) int n4; // expected-error {{less than minimum alignment}}
+alignas(1) alignas(2) int n5 alignas(4); // ok
+alignas(1) alignas(4) int n6 alignas(2); // ok
+alignas(1) int n7 alignas(2), // expected-error {{less than minimum alignment}}
+ n8 alignas(4); // ok
+alignas(8) int n9 alignas(2); // ok, overaligned
+
+enum alignas(1) E1 {}; // expected-error {{requested alignment is less than minimum alignment of 4 for type 'E1'}}
+enum alignas(1) E2 : char {}; // ok
+enum alignas(4) E3 { e3 = 0 }; // ok
+enum alignas(4) E4 { e4 = 1ull << 33 }; // expected-error {{requested alignment is less than minimum alignment of 8 for type 'E4'}}
+
+struct S1 {
+ alignas(8) int n;
+};
+struct alignas(2) S2 { // expected-error {{requested alignment is less than minimum alignment of 4 for type 'S2'}}
+ int n;
+};
+struct alignas(2) S3 { // expected-error {{requested alignment is less than minimum alignment of 8 for type 'S3'}}
+ S1 s1;
+};
+struct alignas(2) S4 : S1 { // expected-error {{requested alignment is less than minimum alignment of 8 for type 'S4'}}
+};
+struct S5 : S1 {
+ alignas(2) S1 s1; // expected-error {{requested alignment is less than minimum alignment of 8 for type 'S1'}}
+};
+struct S6 {
+ S1 s1;
+};
+struct S7 : S1 {
+};
+struct alignas(2) alignas(8) alignas(1) S8 : S1 {
+};
+
+S1 s1 alignas(4); // expected-error {{requested alignment is less than minimum alignment of 8 for type 'S1'}}
+S6 s6 alignas(4); // expected-error {{requested alignment is less than minimum alignment of 8 for type 'S6'}}
+S7 s7 alignas(4); // expected-error {{requested alignment is less than minimum alignment of 8 for type 'S7'}}
+
+template<int N, int M, typename T>
+struct alignas(N) X { // expected-error 3{{requested alignment is less than minimum}}
+ alignas(M) T t; // expected-error 3{{requested alignment is less than minimum}}
+};
+
+template struct X<1, 1, char>;
+template struct X<4, 1, char>;
+template struct X<1, 2, char>; // expected-note {{instantiation}}
+template struct X<1, 1, short>; // expected-note {{instantiation}}
+template struct X<2, 1, short>; // expected-note {{instantiation}}
+template struct X<2, 2, short>;
+template struct X<16, 8, S1>;
+template struct X<4, 4, S1>; // expected-note {{instantiation}}
+
+template<int N, typename T>
+struct Y {
+ enum alignas(N) E : T {}; // expected-error {{requested alignment is less than minimum}}
+};
+template struct Y<1, char>;
+template struct Y<2, char>;
+template struct Y<1, short>; // expected-note {{instantiation}}
+template struct Y<2, short>;
+
+template<int N, typename T>
+void f() {
+ alignas(N) T v; // expected-error {{requested alignment is less than minimum}}
+};
+template void f<1, char>();
+template void f<2, char>();
+template void f<1, short>(); // expected-note {{instantiation}}
+template void f<2, short>();
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p6.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p6.cpp
new file mode 100644
index 0000000..e788577
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p6.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+alignas(4) extern int n1; // expected-note {{previous declaration}}
+alignas(8) int n1; // expected-error {{redeclaration has different alignment requirement (8 vs 4)}}
+
+alignas(8) int n2; // expected-note {{previous declaration}}
+alignas(4) extern int n2; // expected-error {{different alignment requirement (4 vs 8)}}
+
+alignas(8) extern int n3; // expected-note {{previous declaration}}
+alignas(4) extern int n3; // expected-error {{different alignment requirement (4 vs 8)}}
+
+extern int n4;
+alignas(8) extern int n4;
+
+alignas(8) extern int n5;
+extern int n5;
+
+int n6; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+alignas(8) extern int n6; // expected-note {{declared with 'alignas' attribute here}}
+
+extern int n7;
+alignas(8) int n7;
+
+alignas(8) extern int n8; // expected-note {{declared with 'alignas' attribute here}}
+int n8; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+
+int n9; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+alignas(4) extern int n9; // expected-note {{declared with 'alignas' attribute here}}
+
+
+enum alignas(2) E : char; // expected-note {{declared with 'alignas' attribute here}}
+enum E : char {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+
+enum alignas(4) F : char; // expected-note {{previous declaration is here}}
+enum alignas(2) F : char; // expected-error {{redeclaration has different alignment requirement (2 vs 4)}}
+
+enum G : char;
+enum alignas(8) G : char {};
+enum G : char;
+
+enum H : char {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+enum alignas(1) H : char; // expected-note {{declared with 'alignas' attribute here}}
+
+
+struct S;
+struct alignas(16) S; // expected-note {{declared with 'alignas' attribute here}}
+struct S;
+struct S { int n; }; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+
+struct alignas(2) T;
+struct alignas(2) T { char c; }; // expected-note {{previous declaration is here}}
+struct T;
+struct alignas(4) T; // expected-error {{redeclaration has different alignment requirement (4 vs 2)}}
+
+struct U;
+struct alignas(2) U {};
+
+struct V {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
+struct alignas(1) V; // expected-note {{declared with 'alignas' attribute here}}
+
+template<int M, int N> struct alignas(M) W;
+template<int M, int N> struct alignas(N) W {};
+W<4,4> w44; // ok
+// FIXME: We should reject this.
+W<1,2> w12;
+static_assert(alignof(W<4,4>) == 4, "");
+
+template<int M, int N, int O, int P> struct X {
+ alignas(M) alignas(N) static char Buffer[32]; // expected-note {{previous declaration is here}}
+};
+template<int M, int N, int O, int P>
+alignas(O) alignas(P) char X<M, N, O, P>::Buffer[32]; // expected-error {{redeclaration has different alignment requirement (8 vs 2)}}
+char *x1848 = X<1,8,4,8>::Buffer; // ok
+char *x1248 = X<1,2,4,8>::Buffer; // expected-note {{in instantiation of}}
+
+template<int M, int N, int O, int P> struct Y {
+ enum alignas(M) alignas(N) E : char;
+};
+template<int M, int N, int O, int P>
+enum alignas(O) alignas(P) Y<M,N,O,P>::E : char { e };
+int y1848 = Y<1,8,4,8>::e;
+// FIXME: We should reject this.
+int y1248 = Y<1,2,4,8>::e;
+
+// Don't crash here.
+alignas(4) struct Incomplete incomplete; // expected-error {{incomplete type}} expected-note {{forward declaration}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp
new file mode 100644
index 0000000..93b1c64
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<typename T, typename A, int N> struct X {
+ alignas(T) alignas(A) T buffer[N];
+};
+
+static_assert(alignof(X<char, int, sizeof(int)>) == alignof(int), "");
+static_assert(alignof(X<int, char, 1>) == alignof(int), "");
+
+
+template<typename T, typename A, int N> struct Y {
+ alignas(A) T buffer[N]; // expected-error {{requested alignment is less than minimum alignment of 4 for type 'int [1]'}}
+};
+
+static_assert(alignof(Y<char, int, sizeof(int)>) == alignof(int), "");
+static_assert(alignof(Y<int, char, 1>) == alignof(int), ""); // expected-note {{in instantiation of}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
new file mode 100644
index 0000000..686aac2
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+alignas(double) void f(); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
+alignas(double) unsigned char c[sizeof(double)]; // expected-note {{previous}}
+extern unsigned char c[sizeof(double)];
+alignas(float) extern unsigned char c[sizeof(double)]; // expected-error {{different alignment}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
new file mode 100644
index 0000000..9f7ef3a
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+
+[[carries_dependency, carries_dependency]] int m1(); // expected-error {{attribute 'carries_dependency' cannot appear multiple times in an attribute specifier}}
+[[carries_dependency]] [[carries_dependency]] int m2(); // ok
+[[carries_dependency()]] int m3(); // expected-error {{attribute 'carries_dependency' cannot have an argument list}}
+
+[[carries_dependency]] void f1(); // FIXME: warn here
+[[carries_dependency]] int f2(); // ok
+int f3(int param [[carries_dependency]]); // ok
+[[carries_dependency]] int (*f4)(); // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+int (*f5 [[carries_dependency]])(); // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+int (*f6)() [[carries_dependency]]; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
+int (*f7)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
+int (((f8)))(int n [[carries_dependency]]); // ok
+int (*f9(int n))(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
+int typedef f10(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
+using T = int(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
+struct S {
+ [[carries_dependency]] int f(int n [[carries_dependency]]); // ok
+ int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
+};
+void f() {
+ [[carries_dependency]] int f(int n [[carries_dependency]]); // ok
+ [[carries_dependency]] // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+ int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
+}
+
+auto l1 = [](int n [[carries_dependency]]) {};
+// There's no way to write a lambda such that the return value carries
+// a dependency, because an attribute applied to the lambda appertains to
+// the *type* of the operator() function, not to the function itself.
+auto l2 = []() [[carries_dependency]] {}; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp
new file mode 100644
index 0000000..d5b0ebf
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+
+int f(int); // expected-note 2{{declaration missing '[[carries_dependency]]' attribute is here}}
+[[carries_dependency]] int f(int); // expected-error {{function declared '[[carries_dependency]]' after its first declaration}}
+int f(int n [[carries_dependency]]); // expected-error {{parameter declared '[[carries_dependency]]' after its first declaration}}
+
+int g([[carries_dependency]] int n); // expected-note {{declaration missing '[[carries_dependency]]' attribute is here}}
+int g(int);
+[[carries_dependency]] int g(int); // expected-error {{function declared '[[carries_dependency]]' after its first declaration}}
+int g(int n [[carries_dependency]]);
+
+int h [[carries_dependency]]();
+int h();
+[[carries_dependency]] int h();
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
new file mode 100644
index 0000000..0af241f
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fcxx-exceptions %s
+
+[[noreturn]] void a() {
+ return; // expected-warning {{function 'a' declared 'noreturn' should not return}}
+}
+void a2 [[noreturn]] () {
+ return; // expected-warning {{function 'a2' declared 'noreturn' should not return}}
+}
+
+[[noreturn, noreturn]] void b() { throw 0; } // expected-error {{attribute 'noreturn' cannot appear multiple times in an attribute specifier}}
+[[noreturn]] [[noreturn]] void b2() { throw 0; } // ok
+
+[[noreturn()]] void c(); // expected-error {{attribute 'noreturn' cannot have an argument list}}
+
+void d() [[noreturn]]; // expected-error {{'noreturn' attribute cannot be applied to types}}
+int d2 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+
+[[noreturn]] int e() { b2(); } // ok
+
+int f(); // expected-note {{declaration missing '[[noreturn]]' attribute is here}}
+[[noreturn]] int f(); // expected-error {{function declared '[[noreturn]]' after its first declaration}}
+int f();
+
+[[noreturn]] int g();
+int g() { while (true) b(); } // ok
+[[noreturn]] int g();
+
+[[gnu::noreturn]] int h();
+
+template<typename T> void test_type(T) { T::error; } // expected-error {{has no members}}
+template<> void test_type(int (*)()) {}
+
+void check() {
+ // We do not consider [[noreturn]] to be part of the function's type.
+ // However, we do treat [[gnu::noreturn]] as being part of the type.
+ //
+ // This isn't quite GCC-compatible; it treats [[gnu::noreturn]] as
+ // being part of a function *pointer* type, but not being part of
+ // a function type.
+ test_type(e);
+ test_type(f);
+ test_type(g);
+ test_type(h); // expected-note {{instantiation}}
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index 6820fc6..a3a964a 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -25,8 +25,9 @@ constexpr notlit nl1; // expected-error {{constexpr variable cannot have non-lit
void f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}}
// non-static member
struct s2 {
- constexpr int mi1; // expected-error {{non-static data member cannot be constexpr}}
+ constexpr int mi1; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
static constexpr int mi2; // expected-error {{requires an initializer}}
+ mutable constexpr int mi3 = 3; // expected-error-re {{non-static data member cannot be constexpr$}} expected-error {{'mutable' and 'const' cannot be mixed}}
};
// typedef
typedef constexpr int CI; // expected-error {{typedef cannot be constexpr}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index dfc1d3d..ad156c8 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -272,9 +272,8 @@ namespace CtorLookup {
struct A {
constexpr A(const A&) {}
A(A&) {}
- constexpr A(int); // expected-note {{previous}}
+ constexpr A(int = 0);
};
- constexpr A::A(int = 0) {} // expected-warning {{default constructor}}
struct B : A {
B() = default;
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
index 3c1152c..bca73ee 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -verify -std=c++11 -fcxx-exceptions %s
-// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s -DNO_INVALID_CONSTEXPR
namespace StdExample {
@@ -110,3 +110,23 @@ int y1 = Y<int>().get(); // ok
int y2 = Y<Z>().get(); // ok
}
+
+#ifndef NO_INVALID_CONSTEXPR
+namespace PR14550 {
+ // As an "extension", we allow functions which can't produce constant
+ // expressions to be declared constexpr in system headers (libstdc++
+ // marks some functions as constexpr which use builtins which we don't
+ // support constant folding). Ensure that we don't mark those functions
+ // as invalid after suppressing the diagnostic.
+# 122 "p5.cpp" 1 3
+ int n;
+ struct A {
+ static constexpr int f() { return n; }
+ };
+ template<typename T> struct B {
+ B() { g(T::f()); } // expected-error {{undeclared identifier 'g'}}
+ };
+# 130 "p5.cpp" 2
+ template class B<A>; // expected-note {{here}}
+}
+#endif
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
index c4935b3..344f8ce 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
@@ -1,19 +1,39 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+using size_t = decltype(sizeof(int));
+
struct S {
constexpr int f();
constexpr int g() const;
+ constexpr int h();
+ int h();
static constexpr int Sf();
+ /*static*/ constexpr void *operator new(size_t) noexcept;
+ template<typename T> constexpr T tm();
+ template<typename T> static constexpr T ts();
};
void f(const S &s) {
s.f();
s.g();
- int (*f)() = &S::Sf;
+ int (*Sf)() = &S::Sf;
+ int (S::*f)() const = &S::f;
int (S::*g)() const = &S::g;
+ void *(*opNew)(size_t) = &S::operator new;
+ int (S::*tm)() const = &S::tm;
+ int (*ts)() = &S::ts;
}
+constexpr int S::f() const { return 0; }
+constexpr int S::g() { return 1; }
+constexpr int S::h() { return 0; }
+int S::h() { return 0; }
+constexpr int S::Sf() { return 2; }
+constexpr void *S::operator new(size_t) noexcept { return 0; }
+template<typename T> constexpr T S::tm() { return T(); }
+template<typename T> constexpr T S::ts() { return T(); }
+
namespace std_example {
class debug_flag { // expected-note {{not an aggregate and has no constexpr constructors}}
diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp
new file mode 100644
index 0000000..5199330
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -verify %s -std=c++11
+
+// A function that is explicitly defaulted shall
+struct A {
+ // -- be a special member function,
+ A(int) = default; // expected-error {{only special member functions may be defaulted}}
+
+ // -- have the same declared function type as if it had been implicitly
+ // declared
+ void operator=(const A &) = default; // expected-error {{must return 'A &'}}
+ A(...) = default; // expected-error {{cannot be variadic}}
+ A(const A &, ...) = default; // expected-error {{cannot be variadic}}
+
+ // (except for possibly differing ref-qualifiers
+ A &operator=(A &&) & = default;
+
+ // and except that in the case of a copy constructor or copy assignment
+ // operator, the parameter type may be "reference to non-const T")
+ A(A &) = default;
+ A &operator=(A &) = default;
+
+ // -- not have default arguments
+ A(double = 0.0) = default; // expected-error {{cannot have default arguments}}
+ A(const A & = 0) = default; // expected-error {{cannot have default arguments}}
+};
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
index 3450003..d61f6e3 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
@@ -21,7 +21,7 @@ namespace std {
};
}
-namespace bullet2 {
+namespace bullet1 {
double ad[] = { 1, 2.0 };
int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
@@ -62,12 +62,16 @@ namespace bullet4_example3 {
};
S s1 = { 1, 2, 3.0 };
- // FIXME: This is an ill-formed narrowing initialization.
- S s2 { 1.0, 2, 3 };
+ S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
S s3 {};
}
namespace bullet5 {
+ int x1 {2};
+ int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+}
+
+namespace bullet6 {
struct S {
S(std::initializer_list<double>) {}
S(const std::string &) {}
@@ -75,17 +79,12 @@ namespace bullet5 {
const S& r1 = { 1, 2, 3.0 };
const S& r2 = { "Spinach" };
- S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet5::S' cannot bind to an initializer list temporary}}
+ S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet6::S' cannot bind to an initializer list temporary}}
const int& i1 = { 1 };
const int& i2 = { 1.1 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}
const int (&iar)[2] = { 1, 2 };
}
-namespace bullet6 {
- int x1 {2};
- int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
-}
-
namespace bullet7 {
int** pp {};
}
@@ -99,15 +98,25 @@ namespace bullet8 {
B(std::initializer_list<int> i) {}
};
B b1 { 1, 2 };
- B b2 { 1, 2.0 };
+ B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
struct C {
C(int i, double j) {}
};
C c1 = { 1, 2.2 };
- // FIXME: This is an ill-formed narrowing initialization.
- C c2 = { 1.1, 2 }; // expected-warning {{implicit conversion}}
+ // FIXME: Suppress the narrowing warning in the cases where we issue a narrowing error.
+ C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}
int j { 1 };
int k { };
}
+
+namespace rdar13395022 {
+ struct MoveOnly {
+ MoveOnly(MoveOnly&&); // expected-note{{copy constructor is implicitly deleted because 'MoveOnly' has a user-declared move constructor}}
+ };
+
+ void test(MoveOnly mo) {
+ auto &&list = {mo}; // expected-error{{call to implicitly-deleted copy constructor of 'rdar13395022::MoveOnly'}}
+ }
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
index adbdff6..812d0de 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
@@ -192,3 +192,11 @@ namespace PR11003 {
Value y(Move(0));
}
}
+
+namespace rdar13278115 {
+ struct X { };
+ struct Y : X { };
+ X &&f0(X &x) { return x; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::X'}}
+ X &&f1(Y &y) { return y; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}}
+ const X &&f2(Y &y) { return y; } // expected-error{{rvalue reference to type 'const rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}}
+}
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 08d9639..be1113d 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
@@ -3,10 +3,10 @@
// CHECK: example0
void example0() {
double d = 2.0;
- // CHECK: double &rd =
+ // CHECK: VarDecl{{.*}}rd 'double &'
// CHECK-NEXT: DeclRefExpr
double &rd = d;
- // CHECK: const double &rcd =
+ // CHECK: VarDecl{{.*}}rcd 'const double &'
// CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp>
const double &rcd = d;
}
@@ -16,10 +16,10 @@ struct B : A { } b;
// CHECK: example1
void example1() {
- // CHECK: A &ra =
+ // CHECK: VarDecl{{.*}}ra 'struct A &'
// CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
A &ra = b;
- // CHECK: const A &rca =
+ // CHECK: VarDecl{{.*}}rca 'const struct A &'
// CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
const A& rca = b;
@@ -33,12 +33,12 @@ struct X {
// CHECK: example2
void example2() {
- // CHECK: const A &rca =
+ // CHECK: VarDecl{{.*}}rca 'const struct A &'
// CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
// CHECK: CallExpr{{.*}}B
const A &rca = f();
- // CHECK: const A &r =
+ // CHECK: VarDecl{{.*}}r 'const struct A &'
// CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
// CHECK: CXXMemberCallExpr{{.*}}'struct B'
@@ -47,7 +47,7 @@ void example2() {
// CHECK: example3
void example3() {
- // CHECK: const double &rcd2 =
+ // CHECK: VarDecl{{.*}}rcd2 'const double &'
// CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
const double& rcd2 = 2;
}
diff --git a/test/CXX/dcl.decl/dcl.init/p5.cpp b/test/CXX/dcl.decl/dcl.init/p5.cpp
index b50e8d7..e7ccb2e 100644
--- a/test/CXX/dcl.decl/dcl.init/p5.cpp
+++ b/test/CXX/dcl.decl/dcl.init/p5.cpp
@@ -1,20 +1,48 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// FIXME: Very incomplete!
-
// A program that calls for default-initialization or value-initialization of
// an entity of reference type is illformed. If T is a cv-qualified type, the
// cv-unqualified version of T is used for these definitions of
// zero-initialization, default-initialization, and value-initialization.
-//
-// FIXME: The diagnostics for these errors are terrible because they fall out
-// of the AST representation rather than being explicitly issued during the
-// respective initialization forms.
-struct S { // expected-error {{implicit default constructor for 'S' must explicitly initialize the reference member}} \
- // expected-note {{candidate constructor (the implicit copy constructor) not viable}}
- int& x; // expected-note {{declared here}}
+
+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}}
};
S s; // expected-note {{implicit default constructor for 'S' first required here}}
S f() {
- return S(); // expected-error {{no matching constructor for initialization of 'S'}}
+ return S(); // expected-note {{in value-initialization of type 'S' here}}
}
+
+struct T
+ : S { // expected-note 2{{in value-initialization of type 'S' here}}
+};
+T t = T(); // expected-note {{in value-initialization of type 'T' here}}
+
+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}}
+
+// 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
+// recursively apply the value-initialization checks, but we will emit a
+// constructor call anyway, because the default constructor is not trivial.
+struct V {
+ int n;
+ int &r = n; // expected-warning {{C++11}}
+};
+V v = V(); // ok
+struct W {
+ int n;
+ S s = { n }; // expected-warning {{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), "");
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp
index 5467a92..e03c216 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
void nondecl(int (*f)(int x = 5)) // expected-error {{default arguments can only be specified}}
{
@@ -8,6 +8,9 @@ void nondecl(int (*f)(int x = 5)) // expected-error {{default arguments can only
struct X0 {
int (*f)(int = 17); // expected-error{{default arguments can only be specified for parameters in a function declaration}}
+ void (*g())(int = 22); // expected-error{{default arguments can only be specified for parameters in a function declaration}}
+ void (*h(int = 49))(int);
+ auto i(int) -> void (*)(int = 9); // expected-error{{default arguments can only be specified for parameters in a function declaration}}
void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}}
};
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp
index 9b5ef78..4227d82 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp
@@ -38,8 +38,8 @@ namespace copy {
};
struct NonConst {
- NonConst(NonConst&) = default; // expected-error {{must be defaulted outside the class}}
- NonConst& operator=(NonConst&) = default; // expected-error {{must be defaulted outside the class}}
+ NonConst(NonConst&) = default;
+ NonConst& operator=(NonConst&) = default;
};
struct NonConst2 {
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
index 34a8c85..ec1ccbf 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
@@ -1,10 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
struct A { };
-A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}} \
-// expected-error{{out-of-line definition}}
-void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}} \
-// expected-error{{out-of-line definition}}
+A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}}
+void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}}
enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \
// expected-error{{out-of-line definition}}
diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp
index 81fbf7d..9b41f3d 100644
--- a/test/CXX/except/except.spec/p14-ir.cpp
+++ b/test/CXX/except/except.spec/p14-ir.cpp
@@ -27,12 +27,12 @@ struct X5 : X0, X4 { };
void test(X2 x2, X3 x3, X5 x5) {
// CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr
- // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) nounwind
+ // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) [[NUW:#[0-9]+]]
// CHECK-NEXT: ret void
// CHECK-NEXT: }
X2 x2a(x2);
// CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr
- // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) nounwind
+ // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) [[NUW]]
// CHECK-NEXT: ret void
// CHECK-NEXT: }
X3 x3a(x3);
@@ -56,7 +56,7 @@ struct X9 : X6, X7 { };
void test() {
// CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X8* %this) unnamed_addr
- // CHECK: call void @_ZN2X8C2Ev({{.*}}) nounwind
+ // CHECK: call void @_ZN2X8C2Ev({{.*}}) [[NUW]]
// CHECK-NEXT: ret void
X8();
@@ -67,13 +67,15 @@ void test() {
X9();
// CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X9* %this) unnamed_addr
- // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind
+ // CHECK: call void @_ZN2X6C2Ev({{.*}}) [[NUW]]
// FIXME: and here:
// CHECK-NEXT: bitcast
// CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}})
// CHECK: ret void
// CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X8* %this) unnamed_addr
- // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind
+ // CHECK: call void @_ZN2X6C2Ev({{.*}}) [[NUW]]
// CHECK-NEXT: ret void
}
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
index ff21ab8..99ed2fd 100644
--- a/test/CXX/except/except.spec/p14.cpp
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -101,3 +101,14 @@ namespace PR14141 {
~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
};
}
+
+namespace rdar13017229 {
+ struct Base {
+ virtual ~Base() {}
+ };
+
+ struct Derived : Base {
+ virtual ~Derived();
+ Typo foo(); // expected-error{{unknown type name 'Typo'}}
+ };
+}
diff --git a/test/CXX/except/except.spec/p9-noexcept.cpp b/test/CXX/except/except.spec/p9-noexcept.cpp
index 7c8d0ef..3fd45c5 100644
--- a/test/CXX/except/except.spec/p9-noexcept.cpp
+++ b/test/CXX/except/except.spec/p9-noexcept.cpp
@@ -7,9 +7,10 @@ void target() noexcept
// CHECK: invoke void @_Z8externalv()
external();
}
-// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK: [[T0:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
// CHECK-NEXT: catch i8* null
-// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind
+// CHECK-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
+// CHECK-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
// CHECK-NEXT: unreachable
void reverse() noexcept(false)
@@ -17,3 +18,5 @@ void reverse() noexcept(false)
// CHECK: call void @_Z8externalv()
external();
}
+
+// CHECK: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index 9e6716d..065a12b 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -594,3 +594,16 @@ static const bool or_value = and_or<true>::or_value;
static_assert(and_value == false, "");
static_assert(or_value == true, "");
+
+namespace rdar13090123 {
+ typedef __INTPTR_TYPE__ intptr_t;
+
+ constexpr intptr_t f(intptr_t x) {
+ return (((x) >> 21) * 8); // expected-note{{subexpression not valid in a constant expression}}
+ }
+
+ extern "C" int foo;
+
+ constexpr intptr_t i = f((intptr_t)&foo - 10); // expected-error{{constexpr variable 'i' must be initialized by a constant expression}} \
+ // expected-note{{in call to 'f((char*)&foo + -10)'}}
+}
diff --git a/test/CXX/expr/expr.post/expr.call/p7-0x.cpp b/test/CXX/expr/expr.post/expr.call/p7-0x.cpp
index d51ba09..018609d 100644
--- a/test/CXX/expr/expr.post/expr.call/p7-0x.cpp
+++ b/test/CXX/expr/expr.post/expr.call/p7-0x.cpp
@@ -9,11 +9,22 @@ struct X2 {
~X2();
};
+struct X3 {
+ X3(const X3&) = default;
+};
+
+struct X4 {
+ X4(const X4&) = default;
+ X4(X4&);
+};
+
void vararg(...);
-void f(X1 x1, X2 x2) {
- vararg(x1); // okay
+void f(X1 x1, X2 x2, X3 x3, X4 x4) {
+ vararg(x1); // OK
vararg(x2); // expected-error{{cannot pass object of non-trivial type 'X2' through variadic function; call will abort at runtime}}
+ vararg(x3); // OK
+ vararg(x4); // expected-error{{cannot pass object of non-trivial type 'X4' through variadic function; call will abort at runtime}}
}
diff --git a/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
index b84cec6..6657991 100644
--- a/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp
@@ -61,9 +61,26 @@ namespace PR10036 {
}
}
+namespace PR15290 {
+ template<typename T>
+ class A {
+ T v_;
+ friend int add_to_v(A &t) noexcept(noexcept(v_ + 42))
+ {
+ return t.v_ + 42;
+ }
+ };
+ void f()
+ {
+ A<int> t;
+ add_to_v(t);
+ }
+}
+
namespace Static {
struct X1 {
int m;
+ // FIXME: This should be accepted.
static auto f() -> decltype(m); // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}}
@@ -99,3 +116,23 @@ namespace PR12564 {
void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // expected-error {{cannot bind to a value of unrelated type}}
};
}
+
+namespace rdar13473493 {
+ template <typename F>
+ class wrap
+ {
+ public:
+ template <typename... Args>
+ auto operator()(Args&&... args) const -> decltype(wrapped(args...)) // expected-note{{candidate template ignored: substitution failure [with Args = <int>]: use of undeclared identifier 'wrapped'}}
+ {
+ return wrapped(args...);
+ }
+
+ private:
+ F wrapped;
+ };
+
+ void test(wrap<int (*)(int)> w) {
+ w(5); // expected-error{{no matching function for call to object of type 'wrap<int (*)(int)>'}}
+ }
+}
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 6fe3b25..8a6e792 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -13,7 +13,7 @@ void test_special_member_functions(MoveOnly mo, int i) {
decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '<lambda}}
// Copy assignment operator
- lambda1 = lambda1; // expected-error{{overload resolution selected implicitly-deleted copy assignment operator}}
+ lambda1 = lambda1; // expected-error{{copy assignment operator is implicitly deleted}}
// Move assignment operator
lambda1 = move(lambda1);
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
index 68460f0..9dffc1f 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -5,7 +5,8 @@
void test_attributes() {
auto nrl = [](int x) -> int { if (x > 0) return x; }; // expected-warning{{control may reach end of non-void lambda}}
- auto nrl2 = []() [[noreturn]] { return; }; // expected-error{{lambda declared 'noreturn' should not return}}
+ // FIXME: GCC accepts the [[gnu::noreturn]] attribute here.
+ auto nrl2 = []() [[gnu::noreturn]] { return; }; // expected-warning{{attribute 'noreturn' ignored}}
}
template<typename T>
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
index 49b9c66..407b083 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
@@ -2,10 +2,11 @@
template<typename T>
void test_attributes() {
- auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}}
+ // FIXME: GCC accepts [[gnu::noreturn]] here.
+ auto nrl = []() [[gnu::noreturn]] {}; // expected-warning{{attribute 'noreturn' ignored}}
}
-template void test_attributes<int>(); // expected-note{{in instantiation of function}}
+template void test_attributes<int>();
template<typename T>
void call_with_zero() {
diff --git a/test/CXX/lex/lex.literal/lex.ext/p5.cpp b/test/CXX/lex/lex.literal/lex.ext/p5.cpp
index 4655aa17..06c091d 100644
--- a/test/CXX/lex/lex.literal/lex.ext/p5.cpp
+++ b/test/CXX/lex/lex.literal/lex.ext/p5.cpp
@@ -11,3 +11,10 @@ double &i3 = L"foo"_x1; // expected-error {{no matching literal operator}}
char &operator "" _x1(const wchar_t *, size_t);
char &i4 = L"foo"_x1; // ok
double &i5 = R"(foo)"_x1; // ok
+double &i6 = u\
+8\
+R\
+"(foo)"\
+_\
+x\
+1; // ok
diff --git a/test/CXX/lex/lex.pptoken/p3-0x.cpp b/test/CXX/lex/lex.pptoken/p3-0x.cpp
index 3d56ac1..418a0f3 100644
--- a/test/CXX/lex/lex.pptoken/p3-0x.cpp
+++ b/test/CXX/lex/lex.pptoken/p3-0x.cpp
@@ -9,3 +9,7 @@ template void f<::b>();
#define x a<:: ## : b :>
int d = x; // expected-error {{pasting formed ':::', an invalid preprocessing token}} expected-error {{expected unqualified-id}}
+
+const char xs[] = R"(\
+??=\U0000)";
+static_assert(sizeof(xs) == 12, "did not revert all changes");
diff --git a/test/CXX/over/over.oper/over.literal/p8.cpp b/test/CXX/over/over.oper/over.literal/p8.cpp
index 6f63610..70a1843 100644
--- a/test/CXX/over/over.oper/over.literal/p8.cpp
+++ b/test/CXX/over/over.oper/over.literal/p8.cpp
@@ -7,8 +7,7 @@ namespace std {
void operator "" _km(long double); // ok
string operator "" _i18n(const char*, std::size_t); // ok
-// FIXME: This should be accepted once we support UCNs
-template<char...> int operator "" \u03C0(); // ok, UCN for lowercase pi // expected-error {{expected identifier}}
+template<char...> int operator "" \u03C0(); // ok, UCN for lowercase pi // expected-warning {{reserved}}
float operator ""E(const char *); // expected-error {{invalid suffix on literal}} expected-warning {{reserved}}
float operator " " B(const char *); // expected-error {{must be '""'}} expected-warning {{reserved}}
string operator "" 5X(const char *, std::size_t); // expected-error {{expected identifier}}
diff --git a/test/CXX/special/class.copy/implicit-move.cpp b/test/CXX/special/class.copy/implicit-move.cpp
index 597e327..3337412 100644
--- a/test/CXX/special/class.copy/implicit-move.cpp
+++ b/test/CXX/special/class.copy/implicit-move.cpp
@@ -54,7 +54,7 @@ void test_basic_exclusion() {
static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
HasMoveConstructor hmc;
- hmc = HasMoveConstructor(); // expected-error {{selected implicitly-deleted copy assignment}}
+ hmc = HasMoveConstructor(); // expected-error {{object of type 'HasMoveConstructor' cannot be assigned because its copy assignment operator is implicitly deleted}}
(HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
HasMoveAssignment hma;
diff --git a/test/CXX/special/class.copy/p12-0x.cpp b/test/CXX/special/class.copy/p12-0x.cpp
new file mode 100644
index 0000000..17b3191
--- /dev/null
+++ b/test/CXX/special/class.copy/p12-0x.cpp
@@ -0,0 +1,216 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// expected-no-diagnostics
+
+template<typename T, bool B> struct trivially_copyable_check {
+ static_assert(B == __has_trivial_copy(T), "");
+ static_assert(B == __is_trivially_constructible(T, T), "");
+ static_assert(B == __is_trivially_constructible(T, const T &), "");
+ static_assert(B == __is_trivially_constructible(T, T &&), "");
+ typedef void type;
+};
+template<typename T> using trivially_copyable =
+ typename trivially_copyable_check<T, true>::type;
+template<typename T> using not_trivially_copyable =
+ typename trivially_copyable_check<T, false>::type;
+
+struct Trivial {};
+using _ = trivially_copyable<Trivial>;
+
+// A copy/move constructor for class X is trivial if it is not user-provided,
+struct UserProvided {
+ UserProvided(const UserProvided &);
+};
+using _ = not_trivially_copyable<UserProvided>;
+
+// its declared parameter type is the same as if it had been implicitly
+// declared,
+struct NonConstCopy {
+ NonConstCopy(NonConstCopy &) = default;
+};
+using _ = not_trivially_copyable<NonConstCopy>;
+
+// class X has no virtual functions
+struct VFn {
+ virtual void f();
+};
+using _ = not_trivially_copyable<VFn>;
+
+// and no virtual base classes
+struct VBase : virtual Trivial {};
+using _ = not_trivially_copyable<VBase>;
+
+// and the constructor selected to copy/move each [direct subobject] is trivial
+struct TemplateCtor {
+ template<typename T> TemplateCtor(T &);
+};
+using _ = trivially_copyable<TemplateCtor>;
+struct TemplateCtorMember {
+ TemplateCtor tc;
+};
+using _ = trivially_copyable<TemplateCtorMember>;
+
+// We can select a non-trivial copy ctor even if there is a trivial one.
+struct MutableTemplateCtorMember {
+ mutable TemplateCtor mtc;
+};
+static_assert(!__is_trivially_constructible(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");
+static_assert(__is_trivially_constructible(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");
+struct MutableTemplateCtorMember2 {
+ MutableTemplateCtorMember2(const MutableTemplateCtorMember2 &) = default;
+ MutableTemplateCtorMember2(MutableTemplateCtorMember2 &&) = default;
+ mutable TemplateCtor mtc;
+};
+static_assert(!__is_trivially_constructible(MutableTemplateCtorMember2, const MutableTemplateCtorMember2 &), "");
+static_assert(__is_trivially_constructible(MutableTemplateCtorMember2, MutableTemplateCtorMember2 &&), "");
+
+// Both trivial and non-trivial special members.
+struct TNT {
+ TNT(const TNT &) = default; // trivial
+ TNT(TNT &); // non-trivial
+
+ TNT(TNT &&) = default; // trivial
+ TNT(const TNT &&); // non-trivial
+};
+
+static_assert(!__has_trivial_copy(TNT), "lie deliberately for gcc compatibility");
+static_assert(__is_trivially_constructible(TNT, TNT), "");
+static_assert(!__is_trivially_constructible(TNT, TNT &), "");
+static_assert(__is_trivially_constructible(TNT, const TNT &), "");
+static_assert(!__is_trivially_constructible(TNT, volatile TNT &), "");
+static_assert(__is_trivially_constructible(TNT, TNT &&), "");
+static_assert(!__is_trivially_constructible(TNT, const TNT &&), "");
+static_assert(!__is_trivially_constructible(TNT, volatile TNT &&), "");
+
+// This has only trivial special members.
+struct DerivedFromTNT : TNT {};
+
+static_assert(__has_trivial_copy(DerivedFromTNT), "");
+static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT), "");
+static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &), "");
+static_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &), "");
+static_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &), "");
+static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &&), "");
+static_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &&), "");
+static_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &&), "");
+
+// This has only trivial special members.
+struct TNTMember {
+ TNT tnt;
+};
+
+static_assert(__has_trivial_copy(TNTMember), "");
+static_assert(__is_trivially_constructible(TNTMember, TNTMember), "");
+static_assert(__is_trivially_constructible(TNTMember, TNTMember &), "");
+static_assert(__is_trivially_constructible(TNTMember, const TNTMember &), "");
+static_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &), "");
+static_assert(__is_trivially_constructible(TNTMember, TNTMember &&), "");
+static_assert(__is_trivially_constructible(TNTMember, const TNTMember &&), "");
+static_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &&), "");
+
+struct NCCTNT : NonConstCopy, TNT {};
+
+static_assert(!__has_trivial_copy(NCCTNT), "");
+static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT), "");
+static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &), "");
+static_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &), "");
+static_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &), "");
+static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &&), "");
+static_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &&), "");
+static_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &&), "");
+
+struct TemplateCtorNoMove {
+ TemplateCtorNoMove(const TemplateCtorNoMove &) = default;
+ template<typename T> TemplateCtorNoMove(T &&);
+};
+static_assert(__is_trivially_constructible(TemplateCtorNoMove, const TemplateCtorNoMove &), "");
+static_assert(!__is_trivially_constructible(TemplateCtorNoMove, TemplateCtorNoMove &&), "");
+
+struct UseTemplateCtorNoMove {
+ TemplateCtorNoMove tcnm;
+};
+static_assert(__is_trivially_constructible(UseTemplateCtorNoMove, const UseTemplateCtorNoMove &), "");
+static_assert(!__is_trivially_constructible(UseTemplateCtorNoMove, UseTemplateCtorNoMove &&), "");
+
+struct TemplateCtorNoMoveSFINAE {
+ TemplateCtorNoMoveSFINAE(const TemplateCtorNoMoveSFINAE &) = default;
+ template<typename T, typename U = typename T::error> TemplateCtorNoMoveSFINAE(T &&);
+};
+static_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE, const TemplateCtorNoMoveSFINAE &), "");
+static_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE, TemplateCtorNoMoveSFINAE &&), "");
+
+struct UseTemplateCtorNoMoveSFINAE {
+ TemplateCtorNoMoveSFINAE tcnm;
+};
+static_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE, const UseTemplateCtorNoMoveSFINAE &), "");
+static_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE, UseTemplateCtorNoMoveSFINAE &&), "");
+
+namespace TrivialityDependsOnImplicitDeletion {
+ struct PrivateMove {
+ PrivateMove(const PrivateMove &) = default;
+ private:
+ PrivateMove(PrivateMove &&);
+ friend class Access;
+ };
+ static_assert(__is_trivially_constructible(PrivateMove, const PrivateMove &), "");
+ static_assert(!__is_trivially_constructible(PrivateMove, PrivateMove &&), "");
+
+ struct NoAccess {
+ PrivateMove pm;
+ // NoAccess's move would be deleted, so is suppressed,
+ // so moves of it use PrivateMove's copy ctor, which is trivial.
+ };
+ static_assert(__is_trivially_constructible(NoAccess, const NoAccess &), "");
+ static_assert(__is_trivially_constructible(NoAccess, NoAccess &&), "");
+ struct TopNoAccess : NoAccess {};
+ static_assert(__is_trivially_constructible(TopNoAccess, const TopNoAccess &), "");
+ static_assert(__is_trivially_constructible(TopNoAccess, TopNoAccess &&), "");
+
+ struct Access {
+ PrivateMove pm;
+ // NoAccess's move would *not* be deleted, so is *not* suppressed,
+ // so moves of it use PrivateMove's move ctor, which is not trivial.
+ };
+ static_assert(__is_trivially_constructible(Access, const Access &), "");
+ static_assert(!__is_trivially_constructible(Access, Access &&), "");
+ struct TopAccess : Access {};
+ static_assert(__is_trivially_constructible(TopAccess, const TopAccess &), "");
+ static_assert(!__is_trivially_constructible(TopAccess, TopAccess &&), "");
+}
+
+namespace TrivialityDependsOnDestructor {
+ class HasInaccessibleDestructor { ~HasInaccessibleDestructor() = default; };
+ struct HasImplicitlyDeletedDestructor : HasInaccessibleDestructor {};
+ struct HasImplicitlyDeletedCopyCtor : HasImplicitlyDeletedDestructor {
+ HasImplicitlyDeletedCopyCtor() = default;
+ template<typename T> HasImplicitlyDeletedCopyCtor(T &&);
+ // Copy ctor is deleted but trivial.
+ // Move ctor is suppressed.
+ HasImplicitlyDeletedCopyCtor(const HasImplicitlyDeletedCopyCtor&) = default;
+ HasImplicitlyDeletedCopyCtor(HasImplicitlyDeletedCopyCtor&&) = default;
+ };
+ struct Test : HasImplicitlyDeletedCopyCtor {
+ Test(const Test&) = default;
+ Test(Test&&) = default;
+ };
+ // Implicit copy ctor calls deleted trivial copy ctor.
+ static_assert(__has_trivial_copy(Test), "");
+ // This is false because the destructor is deleted.
+ static_assert(!__is_trivially_constructible(Test, const Test &), "");
+ // Implicit move ctor calls template ctor.
+ static_assert(!__is_trivially_constructible(Test, Test &&), "");
+
+ struct HasAccessibleDestructor { ~HasAccessibleDestructor() = default; };
+ struct HasImplicitlyDefaultedDestructor : HasAccessibleDestructor {};
+ struct HasImplicitlyDefaultedCopyCtor : HasImplicitlyDefaultedDestructor {
+ template<typename T> HasImplicitlyDefaultedCopyCtor(T &&);
+ // Copy ctor is trivial.
+ // Move ctor is trivial.
+ };
+ struct Test2 : HasImplicitlyDefaultedCopyCtor {};
+ // Implicit copy ctor calls trivial copy ctor.
+ static_assert(__has_trivial_copy(Test2), "");
+ static_assert(__is_trivially_constructible(Test2, const Test2 &), "");
+ // Implicit move ctor calls trivial move ctor.
+ static_assert(__is_trivially_constructible(Test2, Test2 &&), "");
+}
diff --git a/test/CXX/special/class.copy/p18-cxx11.cpp b/test/CXX/special/class.copy/p18-cxx11.cpp
new file mode 100644
index 0000000..7b09dd6
--- /dev/null
+++ b/test/CXX/special/class.copy/p18-cxx11.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify
+// expected-no-diagnostics
+
+// C++98 [class.copy]p10 / C++11 [class.copy]p18.
+
+// The implicitly-declared copy assignment operator for a class X will have the form
+// X& X::operator=(const X&)
+// if [every direct subobject] has a copy assignment operator whose first parameter is
+// of type 'const volatile[opt] T &' or 'T'. Otherwise, it will have the form
+// X &X::operator=(X&)
+
+struct ConstCopy {
+ ConstCopy &operator=(const ConstCopy &);
+};
+
+struct NonConstCopy {
+ NonConstCopy &operator=(NonConstCopy &);
+};
+
+struct DeletedConstCopy {
+ DeletedConstCopy &operator=(const DeletedConstCopy &) = delete;
+};
+
+struct DeletedNonConstCopy {
+ DeletedNonConstCopy &operator=(DeletedNonConstCopy &) = delete;
+};
+
+struct ImplicitlyDeletedConstCopy {
+ ImplicitlyDeletedConstCopy &operator=(ImplicitlyDeletedConstCopy &&);
+};
+
+struct ByValueCopy {
+ ByValueCopy &operator=(ByValueCopy);
+};
+
+struct AmbiguousConstCopy {
+ AmbiguousConstCopy &operator=(const AmbiguousConstCopy&);
+ AmbiguousConstCopy &operator=(AmbiguousConstCopy);
+};
+
+
+struct A : ConstCopy {};
+struct B : NonConstCopy { ConstCopy a; };
+struct C : ConstCopy { NonConstCopy a; };
+struct D : DeletedConstCopy {};
+struct E : DeletedNonConstCopy {};
+struct F { ImplicitlyDeletedConstCopy a; };
+struct G : virtual B {};
+struct H : ByValueCopy {};
+struct I : AmbiguousConstCopy {};
+
+struct Test {
+ friend A &A::operator=(const A &);
+ friend B &B::operator=(B &);
+ friend C &C::operator=(C &);
+ friend D &D::operator=(const D &);
+ friend E &E::operator=(E &);
+ friend F &F::operator=(const F &);
+ friend G &G::operator=(G &);
+ friend H &H::operator=(const H &);
+ friend I &I::operator=(const I &);
+};
diff --git a/test/CXX/special/class.copy/p23-cxx11.cpp b/test/CXX/special/class.copy/p23-cxx11.cpp
index 7c04a82..90945c5 100644
--- a/test/CXX/special/class.copy/p23-cxx11.cpp
+++ b/test/CXX/special/class.copy/p23-cxx11.cpp
@@ -143,6 +143,6 @@ namespace PR13381 {
};
void g() {
T t;
- t = T(); // expected-error{{implicitly-deleted copy assignment}}
+ t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}}
}
}
diff --git a/test/CXX/special/class.copy/p25-0x.cpp b/test/CXX/special/class.copy/p25-0x.cpp
new file mode 100644
index 0000000..c7224ae
--- /dev/null
+++ b/test/CXX/special/class.copy/p25-0x.cpp
@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// expected-no-diagnostics
+
+template<typename T, bool B> struct trivially_assignable_check {
+ static_assert(B == __has_trivial_assign(T), "");
+ static_assert(B == __is_trivially_assignable(T&, T), "");
+ static_assert(B == __is_trivially_assignable(T&, const T &), "");
+ static_assert(B == __is_trivially_assignable(T&, T &&), "");
+ static_assert(B == __is_trivially_assignable(T&&, T), "");
+ static_assert(B == __is_trivially_assignable(T&&, const T &), "");
+ static_assert(B == __is_trivially_assignable(T&&, T &&), "");
+ typedef void type;
+};
+template<typename T> using trivially_assignable =
+ typename trivially_assignable_check<T, true>::type;
+template<typename T> using not_trivially_assignable =
+ typename trivially_assignable_check<T, false>::type;
+
+struct Trivial {};
+using _ = trivially_assignable<Trivial>;
+
+// A copy/move assignment operator for class X is trivial if it is not user-provided,
+struct UserProvided {
+ UserProvided &operator=(const UserProvided &);
+};
+using _ = not_trivially_assignable<UserProvided>;
+
+// its declared parameter type is the same as if it had been implicitly
+// declared,
+struct NonConstCopy {
+ NonConstCopy &operator=(NonConstCopy &) = default;
+};
+using _ = not_trivially_assignable<NonConstCopy>;
+
+// class X has no virtual functions
+struct VFn {
+ virtual void f();
+};
+using _ = not_trivially_assignable<VFn>;
+
+// and no virtual base classes
+struct VBase : virtual Trivial {};
+using _ = not_trivially_assignable<VBase>;
+
+// and the assignment operator selected to copy/move each [direct subobject] is trivial
+struct TemplateCtor {
+ template<typename T> TemplateCtor operator=(T &);
+};
+using _ = trivially_assignable<TemplateCtor>;
+struct TemplateCtorMember {
+ TemplateCtor tc;
+};
+using _ = trivially_assignable<TemplateCtorMember>;
+struct MutableTemplateCtorMember {
+ mutable TemplateCtor mtc;
+};
+static_assert(!__is_trivially_assignable(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");
+static_assert(__is_trivially_assignable(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");
+
+// Both trivial and non-trivial special members.
+struct TNT {
+ TNT &operator=(const TNT &) = default; // trivial
+ TNT &operator=(TNT &); // non-trivial
+
+ TNT &operator=(TNT &&) = default; // trivial
+ TNT &operator=(const TNT &&); // non-trivial
+};
+
+static_assert(!__has_trivial_assign(TNT), "lie deliberately for gcc compatibility");
+static_assert(__is_trivially_assignable(TNT, TNT), "");
+static_assert(!__is_trivially_assignable(TNT, TNT &), "");
+static_assert(__is_trivially_assignable(TNT, const TNT &), "");
+static_assert(!__is_trivially_assignable(TNT, volatile TNT &), "");
+static_assert(__is_trivially_assignable(TNT, TNT &&), "");
+static_assert(!__is_trivially_assignable(TNT, const TNT &&), "");
+static_assert(!__is_trivially_assignable(TNT, volatile TNT &&), "");
+
+// This has only trivial special members.
+struct DerivedFromTNT : TNT {};
+
+static_assert(__has_trivial_assign(DerivedFromTNT), "");
+static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT), "");
+static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &), "");
+static_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &), "");
+static_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &), "");
+static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &&), "");
+static_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &&), "");
+static_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &&), "");
+
+// This has only trivial special members.
+struct TNTMember {
+ TNT tnt;
+};
+
+static_assert(__has_trivial_assign(TNTMember), "");
+static_assert(__is_trivially_assignable(TNTMember, TNTMember), "");
+static_assert(__is_trivially_assignable(TNTMember, TNTMember &), "");
+static_assert(__is_trivially_assignable(TNTMember, const TNTMember &), "");
+static_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &), "");
+static_assert(__is_trivially_assignable(TNTMember, TNTMember &&), "");
+static_assert(__is_trivially_assignable(TNTMember, const TNTMember &&), "");
+static_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &&), "");
+
+struct NCCTNT : NonConstCopy, TNT {};
+
+static_assert(!__has_trivial_assign(NCCTNT), "");
+static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT), "");
+static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &), "");
+static_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &), "");
+static_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &), "");
+static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &&), "");
+static_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &&), "");
+static_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &&), "");
+
+struct MultipleTrivial {
+ // All four of these are trivial.
+ MultipleTrivial &operator=(const MultipleTrivial &) & = default;
+ MultipleTrivial &operator=(const MultipleTrivial &) && = default;
+ MultipleTrivial &operator=(MultipleTrivial &&) & = default;
+ MultipleTrivial &operator=(MultipleTrivial &&) && = default;
+};
+
+using _ = trivially_assignable<MultipleTrivial>;
+
+struct RefQualifier {
+ RefQualifier &operator=(const RefQualifier &) & = default;
+ RefQualifier &operator=(const RefQualifier &) &&;
+ RefQualifier &operator=(RefQualifier &&) &;
+ RefQualifier &operator=(RefQualifier &&) && = default;
+};
+struct DerivedFromRefQualifier : RefQualifier {
+ // Both of these call the trivial copy operation.
+ DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) & = default;
+ DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) && = default;
+ // Both of these call the non-trivial move operation.
+ DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) & = default;
+ DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) && = default;
+};
+static_assert(__is_trivially_assignable(DerivedFromRefQualifier&, const DerivedFromRefQualifier&), "");
+static_assert(__is_trivially_assignable(DerivedFromRefQualifier&&, const DerivedFromRefQualifier&), "");
+static_assert(!__is_trivially_assignable(DerivedFromRefQualifier&, DerivedFromRefQualifier&&), "");
+static_assert(!__is_trivially_assignable(DerivedFromRefQualifier&&, DerivedFromRefQualifier&&), "");
+
+struct TemplateAssignNoMove {
+ TemplateAssignNoMove &operator=(const TemplateAssignNoMove &) = default;
+ template<typename T> TemplateAssignNoMove &operator=(T &&);
+};
+static_assert(__is_trivially_assignable(TemplateAssignNoMove, const TemplateAssignNoMove &), "");
+static_assert(!__is_trivially_assignable(TemplateAssignNoMove, TemplateAssignNoMove &&), "");
+
+struct UseTemplateAssignNoMove {
+ TemplateAssignNoMove tanm;
+};
+static_assert(__is_trivially_assignable(UseTemplateAssignNoMove, const UseTemplateAssignNoMove &), "");
+static_assert(!__is_trivially_assignable(UseTemplateAssignNoMove, UseTemplateAssignNoMove &&), "");
+
+struct TemplateAssignNoMoveSFINAE {
+ TemplateAssignNoMoveSFINAE &operator=(const TemplateAssignNoMoveSFINAE &) = default;
+ template<typename T, typename U = typename T::error> TemplateAssignNoMoveSFINAE &operator=(T &&);
+};
+static_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, const TemplateAssignNoMoveSFINAE &), "");
+static_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, TemplateAssignNoMoveSFINAE &&), "");
+
+struct UseTemplateAssignNoMoveSFINAE {
+ TemplateAssignNoMoveSFINAE tanm;
+};
+static_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, const UseTemplateAssignNoMoveSFINAE &), "");
+static_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, UseTemplateAssignNoMoveSFINAE &&), "");
+
+namespace TrivialityDependsOnImplicitDeletion {
+ struct PrivateMove {
+ PrivateMove &operator=(const PrivateMove &) = default;
+ private:
+ PrivateMove &operator=(PrivateMove &&);
+ friend class Access;
+ };
+ static_assert(__is_trivially_assignable(PrivateMove, const PrivateMove &), "");
+ static_assert(!__is_trivially_assignable(PrivateMove, PrivateMove &&), "");
+
+ struct NoAccess {
+ PrivateMove pm;
+ // NoAccess's move would be deleted, so is suppressed,
+ // so moves of it use PrivateMove's copy ctor, which is trivial.
+ };
+ static_assert(__is_trivially_assignable(NoAccess, const NoAccess &), "");
+ static_assert(__is_trivially_assignable(NoAccess, NoAccess &&), "");
+ struct TopNoAccess : NoAccess {};
+ static_assert(__is_trivially_assignable(TopNoAccess, const TopNoAccess &), "");
+ static_assert(__is_trivially_assignable(TopNoAccess, TopNoAccess &&), "");
+
+ struct Access {
+ PrivateMove pm;
+ // NoAccess's move would *not* be deleted, so is *not* suppressed,
+ // so moves of it use PrivateMove's move ctor, which is not trivial.
+ };
+ static_assert(__is_trivially_assignable(Access, const Access &), "");
+ static_assert(!__is_trivially_assignable(Access, Access &&), "");
+ struct TopAccess : Access {};
+ static_assert(__is_trivially_assignable(TopAccess, const TopAccess &), "");
+ static_assert(!__is_trivially_assignable(TopAccess, TopAccess &&), "");
+}
diff --git a/test/CXX/special/class.copy/p28-cxx11.cpp b/test/CXX/special/class.copy/p28-cxx11.cpp
new file mode 100644
index 0000000..dc501d9
--- /dev/null
+++ b/test/CXX/special/class.copy/p28-cxx11.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++98 %s -fsyntax-only
+// RUN: %clang_cc1 -std=c++11 %s -verify
+
+// In C++11, we must perform overload resolution to determine which function is
+// called by a defaulted assignment operator, and the selected operator might
+// not be a copy or move assignment (it might be a specialization of a templated
+// 'operator=', for instance).
+struct A {
+ A &operator=(const A &);
+
+ template<typename T>
+ A &operator=(T &&) { return T::error; } // expected-error {{no member named 'error' in 'A'}}
+};
+
+struct B : A {
+ B &operator=(B &&);
+};
+
+B &B::operator=(B &&) = default; // expected-note {{here}}
diff --git a/test/CXX/special/class.ctor/p1.cpp b/test/CXX/special/class.ctor/p1.cpp
index 4d82184..e19dc86 100644
--- a/test/CXX/special/class.ctor/p1.cpp
+++ b/test/CXX/special/class.ctor/p1.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+
struct X0 {
struct type { };
@@ -41,3 +41,15 @@ template<typename T> X1<T>::X1() { }
template<typename T> (X1<T>::X1)(double) { }
template<typename T> X1<T> X1<T>::f1(int) { return 0; }
template<typename T> X1<T> (X1<T>::f1)(type) { return 0; }
+
+class X2 {
+ X2::X2(); // expected-error {{extra qualification on member 'X2'}}
+};
+
+// We used to parse 'X3::X3' as a member function declaration.
+// DR 1435 and DR 1310 made this invalid.
+typedef int T1;
+struct X3 {
+ X3::X3(T1()); // expected-error {{extra qualification on member 'X3'}}
+};
+
diff --git a/test/CXX/special/class.ctor/p5-0x.cpp b/test/CXX/special/class.ctor/p5-0x.cpp
index 1aaeef2..0f4add8 100644
--- a/test/CXX/special/class.ctor/p5-0x.cpp
+++ b/test/CXX/special/class.ctor/p5-0x.cpp
@@ -149,26 +149,41 @@ static_assert(__has_trivial_constructor(Trivial), "Trivial is nontrivial");
class NonTrivialDefCtor1 { NonTrivialDefCtor1(); };
static_assert(!__has_trivial_constructor(NonTrivialDefCtor1), "NonTrivialDefCtor1 is trivial");
+#define ASSERT_NONTRIVIAL_IMPL(Class, Bases, Body) \
+ class Class Bases { Body }; \
+ static_assert(!__has_trivial_constructor(Class), "");
+#define ASSERT_NONTRIVIAL(Class, Bases, Body) \
+ ASSERT_NONTRIVIAL_IMPL(Class, Bases, Body) \
+ ASSERT_NONTRIVIAL_IMPL(Def ## Class, Bases, Def ## Class() = default; Body) \
+ ASSERT_NONTRIVIAL_IMPL(Del ## Class, Bases, Del ## Class() = delete; Body)
+
// - its class has no virtual functions (10.3) and no virtual base classes (10.1), and
-class NonTrivialDefCtor2 { virtual void f(); };
-static_assert(!__has_trivial_constructor(NonTrivialDefCtor2), "NonTrivialDefCtor2 is trivial");
-class NonTrivialDefCtor3 : virtual Trivial {};
-static_assert(!__has_trivial_constructor(NonTrivialDefCtor3), "NonTrivialDefCtor3 is trivial");
+ASSERT_NONTRIVIAL(NonTrivialDefCtor2, , virtual void f();)
+ASSERT_NONTRIVIAL(NonTrivialDefCtor3, : virtual Trivial, )
// - no non-static data member of its class has a brace-or-equal-initializer, and
-class NonTrivialDefCtor4 { int m = 52; };
-static_assert(!__has_trivial_constructor(NonTrivialDefCtor4), "NonTrivialDefCtor4 is trivial");
+ASSERT_NONTRIVIAL(NonTrivialDefCtor4, , int m = 52;)
// - all the direct base classes of its class have trivial default constructors, and
-class NonTrivialDefCtor5 : NonTrivialDefCtor1 {};
-static_assert(!__has_trivial_constructor(NonTrivialDefCtor5), "NonTrivialDefCtor5 is trivial");
+ASSERT_NONTRIVIAL(NonTrivialDefCtor5, : NonTrivialDefCtor1, )
// - for all the non-static data members of its class that are of class type (or array thereof), each such class
// has a trivial default constructor.
-class NonTrivialDefCtor6 { NonTrivialDefCtor1 t; };
-static_assert(!__has_trivial_constructor(NonTrivialDefCtor6), "NonTrivialDefCtor5 is trivial");
+ASSERT_NONTRIVIAL(NonTrivialDefCtor6, , NonTrivialDefCtor1 t;)
+
+// FIXME: No core issue number yet.
+// - its parameter-declaration-clause is equivalent to that of an implicit declaration.
+struct NonTrivialDefCtor7 {
+ NonTrivialDefCtor7(...) = delete;
+};
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor7), "");
+struct NonTrivialDefCtor8 {
+ NonTrivialDefCtor8(int = 0) = delete;
+};
+static_assert(!__has_trivial_constructor(NonTrivialDefCtor8), "");
// Otherwise, the default constructor is non-trivial.
+
class Trivial2 { Trivial2() = delete; };
static_assert(__has_trivial_constructor(Trivial2), "Trivial2 is trivial");
@@ -180,3 +195,15 @@ static_assert(__has_trivial_constructor(Trivial4<int>), "Trivial4 is trivial");
template<typename T> class Trivial5 { Trivial5() = delete; };
static_assert(__has_trivial_constructor(Trivial5<int>), "Trivial5 is trivial");
+
+namespace PR14558 {
+ // Ensure we determine whether an explicitly-defaulted or deleted special
+ // member is trivial before we return to parsing the containing class.
+ struct A {
+ struct B { B() = default; } b;
+ struct C { C() = delete; } c;
+ };
+
+ static_assert(__has_trivial_constructor(A), "");
+ static_assert(__has_trivial_constructor(A::B), "");
+}
diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp
index 291353a..dc76e00 100644
--- a/test/CXX/special/class.dtor/p3-0x.cpp
+++ b/test/CXX/special/class.dtor/p3-0x.cpp
@@ -164,14 +164,16 @@ void tsw() {
Sw<int> swi;
Sw<B> swb;
}
-// CHECK-NOT: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} nounwind
+// CHECK-NOT: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} #
// CHECK: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}}
// CHECK: _ZTIi
// CHECK: __cxa_call_unexpected
-// CHECK: define linkonce_odr {{.*}} @_ZN2SwIiED1Ev({{.*}} nounwind
+// CHECK: define linkonce_odr {{.*}} @_ZN2SwIiED1Ev({{.*}} [[ATTRGRP:#[0-9]+]]
template <typename T>
struct TVC : VX
{ virtual ~TVC(); };
template <typename T>
TVC<T>::~TVC() {}
+
+// CHECK: attributes [[ATTRGRP]] = { nounwind{{.*}} }
diff --git a/test/CXX/special/class.dtor/p5-0x.cpp b/test/CXX/special/class.dtor/p5-0x.cpp
index 0d073ce..e32279e 100644
--- a/test/CXX/special/class.dtor/p5-0x.cpp
+++ b/test/CXX/special/class.dtor/p5-0x.cpp
@@ -88,9 +88,10 @@ struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted f
class D1 {
void operator delete(void*);
public:
- virtual ~D1() = default;
+ 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 {{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}}
struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp
index 09fd3d5..184e902 100644
--- a/test/CXX/special/class.inhctor/elsewhere.cpp
+++ b/test/CXX/special/class.inhctor/elsewhere.cpp
@@ -9,49 +9,49 @@ struct B1 {
B1(int);
};
-using B1::B1; // expected-error {{using declaration can not refer to class member}} expected-error {{not supported}}
+using B1::B1; // expected-error {{using declaration can not refer to class member}}
-// C++0x [namespace.udecl]p10:
+// C++11 [namespace.udecl]p10:
// A using-declaration is a declaration and can therefore be used repeatedly
// where (and only where) multiple declarations are allowed.
struct I1 : B1 {
- using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}}
- using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}}
+ using B1::B1; // expected-note {{previous using declaration}}
+ using B1::B1; // expected-error {{redeclaration of using decl}}
};
-// C++0x [namespace.udecl]p3:
+// C++11 [namespace.udecl]p3:
// In a using declaration used as a member-declaration, the nested-name-
// specifier shall name a base class of the class being defined.
// If such a using-declaration names a constructor, the nested-name-specifier
// shall name a direct base class of the class being defined.
struct D1 : I1 {
- using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} expected-error {{not supported}}
+ using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}}
};
template<typename T> struct A {};
template<typename T> struct B : A<bool>, A<char> {
- using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} expected-error {{not supported}}
+ using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}}
};
B<bool> bb;
B<char> bc;
B<double> bd; // expected-note {{here}}
template<typename T> struct C : A<T> {
- using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} expected-error {{not supported}}
+ using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}}
};
C<bool> cb;
C<char> cc; // expected-note {{here}}
template<typename T> struct D : A<T> {};
template<typename T> struct E : D<T> {
- using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} expected-error {{not supported}}
+ using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}}
};
E<bool> eb; // expected-note {{here}}
template<typename T> struct F : D<bool> {
- using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} expected-error {{not supported}}
+ using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}}
};
F<bool> fb; // expected-note {{here}}
diff --git a/test/CXX/special/class.inhctor/p1.cpp b/test/CXX/special/class.inhctor/p1.cpp
new file mode 100644
index 0000000..57e9150
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p1.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+// Per a core issue (no number yet), an ellipsis is always dropped.
+struct A {
+ A(...); // expected-note {{here}}
+ A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 5{{here}}
+ A(int = 0, int = 0, ...); // expected-note {{here}}
+};
+
+struct B : A { // expected-note 3{{candidate}}
+ using A::A; // expected-warning 3{{inheriting constructor does not inherit ellipsis}} expected-note 4{{candidate}} expected-note 2{{deleted}}
+};
+
+B b0{};
+// expected-error@-1 {{call to implicitly-deleted default constructor}}
+// expected-note@9 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}}
+
+B b1{1};
+// FIXME: explain why the inheriting constructor was deleted
+// expected-error@-2 {{call to implicitly-deleted function of 'B'}}
+
+B b2{1,2};
+// expected-error@-1 {{call to implicitly-deleted function of 'B'}}
+
+B b3{1,2,3};
+// ok
+
+B b4{1,2,3,4};
+// ok
+
+B b5{1,2,3,4,5};
+// expected-error@-1 {{no matching constructor for initialization of 'B'}}
diff --git a/test/CXX/special/class.inhctor/p2.cpp b/test/CXX/special/class.inhctor/p2.cpp
new file mode 100644
index 0000000..e426738
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p2.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<int> struct X {};
+
+// Constructor characteristics are:
+// - the template parameter list [FIXME]
+// - the parameter-type-list
+// - absence or presence of explicit
+// - absence or presence of constexpr
+struct A {
+ A(X<0>) {} // expected-note 2{{here}}
+ constexpr A(X<1>) {}
+ explicit A(X<2>) {} // expected-note 3{{here}}
+ explicit constexpr A(X<3>) {} // expected-note 2{{here}}
+};
+
+A a0 { X<0>{} };
+A a0i = { X<0>{} };
+constexpr A a0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr A a0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+
+A a1 { X<1>{} };
+A a1i = { X<1>{} };
+constexpr A a1c { X<1>{} };
+constexpr A a1ic = { X<1>{} };
+
+A a2 { X<2>{} };
+A a2i = { X<2>{} }; // expected-error {{constructor is explicit}}
+constexpr A a2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr A a2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
+
+A a3 { X<3>{} };
+A a3i = { X<3>{} }; // expected-error {{constructor is explicit}}
+constexpr A a3c { X<3>{} };
+constexpr A a3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
+
+
+struct B : A {
+ using A::A; // expected-note 7{{here}}
+};
+
+B b0 { X<0>{} };
+B b0i = { X<0>{} };
+constexpr B b0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr B b0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+
+B b1 { X<1>{} };
+B b1i = { X<1>{} };
+constexpr B b1c { X<1>{} };
+constexpr B b1ic = { X<1>{} };
+
+B b2 { X<2>{} };
+B b2i = { X<2>{} }; // expected-error {{constructor is explicit}}
+constexpr B b2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
+constexpr B b2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
+
+B b3 { X<3>{} };
+B b3i = { X<3>{} }; // expected-error {{constructor is explicit}}
+constexpr B b3c { X<3>{} };
+constexpr B b3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
+
+
+// 'constexpr' is OK even if the constructor doesn't obey the constraints.
+struct NonLiteral { NonLiteral(); };
+struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; // expected-note {{here}}
+struct Constexpr { constexpr Constexpr(int) {} };
+
+struct BothNonLiteral : NonLiteral, Constexpr { using Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of non-literal type}}
+constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr variable cannot have non-literal type 'const BothNonLiteral'}}
+
+struct BothNonConstexpr : NonConstexpr, Constexpr { using Constexpr::Constexpr; }; // expected-note {{non-constexpr constructor 'NonConstexpr}}
+constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'BothNonConstexpr(42)'}}
+
+
+struct ConstexprEval {
+ constexpr ConstexprEval(int a, const char *p) : k(p[a]) {}
+ char k;
+};
+struct ConstexprEval2 {
+ char k2 = 'x';
+};
+struct ConstexprEval3 : ConstexprEval, ConstexprEval2 {
+ using ConstexprEval::ConstexprEval;
+};
+constexpr ConstexprEval3 ce{4, "foobar"};
+static_assert(ce.k == 'a', "");
+static_assert(ce.k2 == 'x', "");
diff --git a/test/CXX/special/class.inhctor/p3.cpp b/test/CXX/special/class.inhctor/p3.cpp
index d7093fb..f71ab16 100644
--- a/test/CXX/special/class.inhctor/p3.cpp
+++ b/test/CXX/special/class.inhctor/p3.cpp
@@ -5,7 +5,7 @@ struct B1 {
B1(int, int);
};
struct D1 : B1 {
- using B1::B1; // expected-error {{not supported}}
+ using B1::B1;
};
D1 d1a(1), d1b(1, 1);
@@ -15,7 +15,7 @@ struct B2 {
explicit B2(int, int = 0, int = 0);
};
struct D2 : B2 { // expected-note 2 {{candidate constructor}}
- using B2::B2; // expected-error {{not supported}}
+ using B2::B2;
};
D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
@@ -25,18 +25,18 @@ struct B3 {
B3(void*); // expected-note {{inherited from here}}
};
struct D3 : B3 { // expected-note 2 {{candidate constructor}}
- using B3::B3; // expected-note {{candidate constructor (inherited)}} expected-error {{not supported}}
+ using B3::B3; // expected-note {{candidate constructor (inherited)}}
};
D3 fd3() { return 1; } // expected-error {{no viable conversion}}
template<typename T> struct T1 : B1 {
- using B1::B1; // expected-error {{not supported}}
+ using B1::B1;
};
template<typename T> struct T2 : T1<T> {
- using T1<int>::T1; // expected-error {{not supported}}
+ using T1<int>::T1;
};
template<typename T> struct T3 : T1<int> {
- using T1<T>::T1; // expected-error {{not supported}}
+ using T1<T>::T1;
};
struct U {
friend T1<int>::T1(int);
diff --git a/test/CXX/special/class.inhctor/p4.cpp b/test/CXX/special/class.inhctor/p4.cpp
new file mode 100644
index 0000000..eea3bf2
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p4.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<int> struct X {};
+
+// A[n inheriting] constructor [...] has the same access as the corresponding
+// constructor [in the base class].
+struct A {
+public:
+ A(X<0>) {}
+protected:
+ A(X<1>) {}
+private:
+ A(X<2>) {} // expected-note {{declared private here}}
+ friend class FA;
+};
+
+struct B : A {
+ using A::A; // expected-error {{private constructor}} expected-note {{implicitly declared protected here}}
+ friend class FB;
+};
+
+B b0{X<0>{}};
+B b1{X<1>{}}; // expected-error {{calling a protected constructor}}
+B b2{X<2>{}}; // expected-note {{first required here}}
+
+struct C : B {
+ C(X<0> x) : B(x) {}
+ C(X<1> x) : B(x) {}
+};
+
+struct FB {
+ B b0{X<0>{}};
+ B b1{X<1>{}};
+};
+
+struct FA : A {
+ using A::A; // expected-note 2{{here}}
+};
+FA fa0{X<0>{}};
+FA fa1{X<1>{}}; // expected-error {{calling a protected constructor}}
+FA fa2{X<2>{}}; // expected-error {{calling a private constructor}}
+
+
+// It is deleted if the corresponding constructor [...] is deleted.
+struct G {
+ G(int) = delete;
+};
+struct H : G {
+ using G::G; // expected-note {{marked deleted here}}
+};
+H h(5); // expected-error {{call to implicitly-deleted function of 'H'}}
+
+
+// Core defect: It is also deleted if multiple base constructors generate the
+// same signature.
+namespace DRnnnn {
+ struct A {
+ constexpr A(int, float = 0) {}
+ explicit A(int, int = 0) {}
+
+ A(int, int, int = 0) = delete;
+ };
+ struct B : A {
+ // FIXME: produce notes indicating why it was deleted
+ using A::A; // expected-note {{here}}
+ };
+
+ constexpr B b0(0, 0.0f); // ok, constexpr
+ B b1(0, 1); // expected-error {{call to implicitly-deleted}}
+}
diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp
index bfaa3ac..9ae160f 100644
--- a/test/CXX/special/class.inhctor/p7.cpp
+++ b/test/CXX/special/class.inhctor/p7.cpp
@@ -8,12 +8,12 @@ struct B2 {
B2(int); // expected-note {{conflicting constructor}}
};
struct D1 : B1, B2 {
- using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}}
- using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}}
+ using B1::B1; // expected-note {{inherited here}}
+ using B2::B2; // expected-error {{already inherited constructor with the same signature}}
};
struct D2 : B1, B2 {
- using B1::B1; // expected-error {{not supported}}
- using B2::B2; // expected-error {{not supported}}
+ using B1::B1;
+ using B2::B2;
D2(int);
};
@@ -22,8 +22,8 @@ template<typename T> struct B3 {
};
template<typename T> struct B4 : B3<T>, B1 {
B4();
- using B3<T>::B3; // expected-note {{inherited here}} expected-error {{not supported}}
- using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}}
+ using B3<T>::B3; // expected-note {{inherited here}}
+ using B1::B1; // expected-error {{already inherited}}
};
B4<char> b4c;
B4<int> b4i; // expected-note {{here}}
diff --git a/test/CXX/special/class.inhctor/p8.cpp b/test/CXX/special/class.inhctor/p8.cpp
new file mode 100644
index 0000000..e2b07df
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p8.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// expected-no-diagnostics
+struct A {
+ constexpr A(const int&) : rval(false) {}
+ constexpr A(const int&&) : rval(true) {}
+ bool rval;
+};
+struct B : A {
+ using A::A;
+};
+
+constexpr int k = 0;
+constexpr A a0{0};
+constexpr A a1{k};
+constexpr B b0{0};
+// This performs static_cast<(const int&)&&>(k), so calls the A(const int&)
+// constructor.
+constexpr B b1{k};
+
+static_assert(a0.rval && !a1.rval && b0.rval && !b1.rval, "");
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 726e222..9453798 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -351,6 +351,15 @@ void test_unexpanded_exprs(Types ...values) {
// FIXME: Objective-C expressions will need to go elsewhere
for (auto t : values) { } // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ switch (values) { } // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ do { } while (values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+test:
+ goto *values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ void f(int arg = values); // expected-error{{default argument contains unexpanded parameter pack 'values'}}
}
// Test unexpanded parameter packs in partial specializations.
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.mm b/test/CXX/temp/temp.decls/temp.variadic/p5.mm
new file mode 100644
index 0000000..d059826
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.mm
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fobjc-exceptions -fexceptions -std=c++11 -fblocks -fsyntax-only -verify %s
+
+template<typename...Types>
+void f(Types ...values) {
+ for (id x in values) { } // expected-error {{expression contains unexpanded parameter pack 'values'}}
+ @synchronized(values) { // expected-error {{expression contains unexpanded parameter pack 'values'}}
+ @throw values; // expected-error {{expression contains unexpanded parameter pack 'values'}}
+ }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
index 36b0700..dcf5a08 100644
--- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
@@ -26,3 +26,24 @@ namespace ParameterPacksWithFunctions {
unsigned_c<2> uc2 = f<float, double>();
}
}
+
+namespace rdar12176336 {
+ typedef void (*vararg_func)(...);
+
+ struct method {
+ vararg_func implementation;
+
+ method(vararg_func implementation) : implementation(implementation) {}
+
+ template<typename TReturnType, typename... TArguments, typename TFunctionType = TReturnType (*)(TArguments...)>
+ auto getImplementation() const -> TFunctionType
+ {
+ return reinterpret_cast<TFunctionType>(implementation);
+ }
+ };
+
+ void f() {
+ method m(nullptr);
+ auto imp = m.getImplementation<int, int, int>();
+ }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
index 90d2949..33efac0 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
@@ -15,8 +15,7 @@ void test_f1(int *ip, float fv) {
f1(ip, fv);
}
-// TODO: this diagnostic can and should improve
-template<typename T> void f2(T*, T*); // expected-note {{candidate template ignored: failed template argument deduction}} \
+template<typename T> void f2(T*, T*); // expected-note {{candidate template ignored: could not match 'T *' against 'ConvToIntPtr'}} \
// expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
struct ConvToIntPtr {
@@ -28,3 +27,21 @@ void test_f2(int *ip, float *fp) {
f2(ip, ip); // okay
f2(ip, fp); // expected-error{{no matching function}}
}
+
+namespace test3 {
+ template<typename T>
+ struct bar { };
+
+ template<typename T>
+ struct foo {
+ operator bar<T>();
+ };
+
+ template<typename T>
+ void func(bar<T>) { // expected-note {{candidate template ignored: could not match 'bar' against 'foo'}}
+ }
+
+ void test() {
+ func(foo<int>()); // expected-error {{no matching function}}
+ }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
index 8b192fa..cd1d9f1 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
@@ -53,8 +53,9 @@ void test_simple_ref_deduction(int *ip, float *fp, double *dp) {
}
+// FIXME: Use the template parameter names in this diagnostic.
template<typename ...Args1, typename ...Args2>
-typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: failed template argument deduction}}
+typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'int'}}
template<typename ...Args1, typename ...Args2>
typename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...);
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 7774b5c..d7989e3 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
@@ -53,3 +53,16 @@ namespace DeduceNonTypeTemplateArgsInArray {
tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
>::value? 1 : -1];
}
+
+namespace DeduceWithDefaultArgs {
+ template<template<typename...> class Container> void f(Container<int>); // expected-note {{substitution failure [with Container = X]}}
+ template<typename, typename = int> struct X {};
+ void g() {
+ // OK, use default argument for the second template parameter.
+ f(X<int>{});
+ f(X<int, int>{});
+
+ // Not OK.
+ f(X<int, double>{}); // expected-error {{no matching function for call to 'f'}}
+ }
+}
diff --git a/test/CXX/temp/temp.res/temp.dep/p3.cpp b/test/CXX/temp/temp.res/temp.dep/p3.cpp
index 88b4752..583fb4b 100644
--- a/test/CXX/temp/temp.res/temp.dep/p3.cpp
+++ b/test/CXX/temp/temp.res/temp.dep/p3.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
struct A0 {
struct K { };
};
@@ -42,3 +41,49 @@ namespace E2 {
Y<A> ya;
}
+
+namespace PR14402 {
+ template<typename T>
+ struct A {
+ typedef int n;
+ int f();
+
+ struct B {};
+ struct C : B {
+ // OK, can't be sure whether we derive from A yet.
+ using A::n;
+ int g() { return f(); }
+ };
+
+ struct D {
+ using A::n; // expected-error {{using declaration refers into 'A<T>::', which is not a base class of 'D'}}
+ int g() { return f(); } // expected-error {{call to non-static member function 'f' of 'A' from nested type 'D'}}
+ };
+
+ struct E { char &f(); };
+ struct F : E {
+ // FIXME: Reject this prior to instantiation; f() is known to return int.
+ char &g() { return f(); }
+ // expected-error@-1 {{'PR14402::A<int>::f' is not a member of class 'PR14402::A<int>::F'}}
+ // expected-error@-2 {{non-const lvalue reference to type 'char' cannot bind to a temporary of type 'int'}}
+ };
+ };
+
+ template<> struct A<int>::B : A<int> {};
+ A<int>::C::n n = A<int>::C().g();
+
+ // 'not a member'
+ char &r = A<int>::F().g(); // expected-note {{in instantiation of}}
+ template<> struct A<char>::E : A<char> {};
+ // 'cannot bind to a temporary'
+ char &s = A<char>::F().g(); // expected-note {{in instantiation of}}
+
+ struct X;
+ struct X { void f(); };
+ struct X;
+ template<typename T> struct Y : X {
+ void g() {
+ X::f();
+ }
+ };
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
index b0a19fb..75b198e 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
@@ -300,3 +300,8 @@ template<> template<typename T>
void has_inline_namespaces::X0<X4>::mem_func_template(T&) { }
template<> int has_inline_namespaces::X0<X4>::value = 13;
+
+namespace PR12938 {
+ template<typename> [[noreturn]] void func();
+ template<> void func<int>();
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
index 80f0598..e0c7b35 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
@@ -12,7 +12,7 @@ struct Y {
constexpr int f() { return 0; }
};
-template constexpr int Y<int>::f(); // expected-error{{explicit instantiation cannot be 'constexpr'}}
+template constexpr int Y<int>::f() const; // expected-error{{explicit instantiation cannot be 'constexpr'}}
template<typename T>
struct Z {
OpenPOWER on IntegriCloud