summaryrefslogtreecommitdiff
path: root/clang/test/CXX/dcl.dcl/dcl.spec
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/dcl.dcl/dcl.spec
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/dcl.dcl/dcl.spec')
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp123
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp26
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp139
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp249
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp112
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp68
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp38
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp37
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp13
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp7
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp16
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp32
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp14
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp26
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp11
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp49
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp51
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp43
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp68
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp104
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp32
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp19
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp61
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp27
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp108
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp43
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp160
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp8
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp15
29 files changed, 1699 insertions, 0 deletions
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
new file mode 100644
index 0000000..6820fc6
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct notlit { // expected-note {{not literal because}}
+ notlit() {}
+};
+struct notlit2 {
+ notlit2() {}
+};
+
+// valid declarations
+constexpr int i1 = 0;
+constexpr int f1() { return 0; }
+struct s1 {
+ constexpr static int mi1 = 0;
+ const static int mi2;
+};
+constexpr int s1::mi2 = 0;
+
+// invalid declarations
+// not a definition of an object
+constexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}}
+// not a literal type
+constexpr notlit nl1; // expected-error {{constexpr variable cannot have non-literal type 'const notlit'}}
+// function parameters
+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}}
+ static constexpr int mi2; // expected-error {{requires an initializer}}
+};
+// typedef
+typedef constexpr int CI; // expected-error {{typedef cannot be constexpr}}
+// tag
+constexpr class C1 {}; // expected-error {{class cannot be marked constexpr}}
+constexpr struct S1 {}; // expected-error {{struct cannot be marked constexpr}}
+constexpr union U1 {}; // expected-error {{union cannot be marked constexpr}}
+constexpr enum E1 {}; // expected-error {{enum cannot be marked constexpr}}
+template <typename T> constexpr class TC1 {}; // expected-error {{class cannot be marked constexpr}}
+template <typename T> constexpr struct TS1 {}; // expected-error {{struct cannot be marked constexpr}}
+template <typename T> constexpr union TU1 {}; // expected-error {{union cannot be marked constexpr}}
+class C2 {} constexpr; // expected-error {{class cannot be marked constexpr}}
+struct S2 {} constexpr; // expected-error {{struct cannot be marked constexpr}}
+union U2 {} constexpr; // expected-error {{union cannot be marked constexpr}}
+enum E2 {} constexpr; // expected-error {{enum cannot be marked constexpr}}
+constexpr class C3 {} c3 = C3();
+constexpr struct S3 {} s3 = S3();
+constexpr union U3 {} u3 = {};
+constexpr enum E3 { V3 } e3 = V3;
+class C4 {} constexpr c4 = C4();
+struct S4 {} constexpr s4 = S4();
+union U4 {} constexpr u4 = {};
+enum E4 { V4 } constexpr e4 = V4;
+constexpr int; // expected-error {{constexpr can only be used in variable and function declarations}}
+// redeclaration mismatch
+constexpr int f3(); // expected-note {{previous declaration is here}}
+int f3(); // expected-error {{non-constexpr declaration of 'f3' follows constexpr declaration}}
+int f4(); // expected-note {{previous declaration is here}}
+constexpr int f4(); // expected-error {{constexpr declaration of 'f4' follows non-constexpr declaration}}
+template<typename T> constexpr T f5(T);
+template<typename T> constexpr T f5(T); // expected-note {{previous}}
+template<typename T> T f5(T); // expected-error {{non-constexpr declaration of 'f5' follows constexpr declaration}}
+template<typename T> T f6(T); // expected-note {{here}}
+template<typename T> constexpr T f6(T); // expected-error {{constexpr declaration of 'f6' follows non-constexpr declaration}}
+// destructor
+struct ConstexprDtor {
+ constexpr ~ConstexprDtor() = default; // expected-error {{destructor cannot be marked constexpr}}
+};
+
+// template stuff
+template <typename T> constexpr T ft(T t) { return t; }
+template <typename T> T gt(T t) { return t; }
+struct S {
+ template<typename T> constexpr T f();
+ template<typename T> T g() const;
+};
+
+// explicit specialization can differ in constepxr
+template <> notlit ft(notlit nl) { return nl; }
+template <> char ft(char c) { return c; } // expected-note {{previous}}
+template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
+template <> constexpr int gt(int nl) { return nl; }
+template <> notlit S::f() const { return notlit(); }
+template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
+// specializations can drop the 'constexpr' but not the implied 'const'.
+template <> char S::g() { return 0; } // expected-error {{no function template matches}}
+template <> double S::g() const { return 0; } // ok
+
+constexpr int i3 = ft(1);
+
+void test() {
+ // ignore constexpr when instantiating with non-literal
+ notlit2 nl2;
+ (void)ft(nl2);
+}
+
+// Examples from the standard:
+constexpr int square(int x); // expected-note {{declared here}}
+constexpr int bufsz = 1024;
+
+constexpr struct pixel { // expected-error {{struct cannot be marked constexpr}}
+ int x;
+ int y;
+ constexpr pixel(int);
+};
+
+constexpr pixel::pixel(int a)
+ : x(square(a)), y(square(a)) // expected-note {{undefined function 'square' cannot be used in a constant expression}}
+ { }
+
+constexpr pixel small(2); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'pixel(2)'}}
+
+constexpr int square(int x) {
+ return x * x;
+}
+
+constexpr pixel large(4);
+
+int next(constexpr int x) { // expected-error {{function parameter cannot be constexpr}}
+ return x + 1;
+}
+
+extern constexpr int memsz; // expected-error {{constexpr variable declaration must be a definition}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
new file mode 100644
index 0000000..001a086
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - | FileCheck %s
+
+// constexpr functions and constexpr constructors are implicitly inline.
+struct S {
+ constexpr S(int n);
+ constexpr int g();
+ int n;
+};
+
+constexpr S::S(int n) : n(n) {}
+
+constexpr S f(S s) {
+ return s.n * 2;
+}
+
+constexpr int S::g() {
+ return f(*this).n;
+}
+
+// CHECK: define linkonce_odr {{.*}} @_Z1f1S(
+// CHECK: define linkonce_odr {{.*}} @_ZN1SC1Ei(
+// CHECK: define linkonce_odr {{.*}} @_ZNK1S1gEv(
+
+int g() {
+ return f(42).g();
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
new file mode 100644
index 0000000..cafdd63
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -0,0 +1,139 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+
+namespace N {
+ typedef char C;
+}
+
+namespace M {
+ typedef double D;
+}
+
+struct NonLiteral { // expected-note 2{{no constexpr constructors}}
+ NonLiteral() {}
+ NonLiteral(int) {}
+};
+struct Literal {
+ constexpr Literal() {}
+ operator int() const { return 0; }
+};
+
+struct S {
+ virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
+};
+struct SS : S {
+ int ImplicitlyVirtual() const;
+};
+
+// The definition of a constexpr function shall satisfy the following
+// constraints:
+struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
+ constexpr T();
+ constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
+
+ // - it shall not be virtual;
+ virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
+
+ constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
+
+ // - its return type shall be a literal type;
+ constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
+ constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}}
+ constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
+ typedef NonLiteral F();
+ constexpr F NonLiteralReturn2; // ok until definition
+
+ // - each of its parameter types shall be a literal type;
+ constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
+ typedef int G(NonLiteral);
+ constexpr G NonLiteralParam2; // ok until definition
+
+ // - its function-body shall be = delete, = default,
+ constexpr int Deleted() = delete;
+ // It's not possible for the function-body to legally be "= default" here.
+ // Other than constructors, only the copy- and move-assignment operators and
+ // destructor can be defaulted. Destructors can't be constexpr since they
+ // don't have a literal return type. Defaulted assignment operators can't be
+ // constexpr since they can't be const.
+ constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
+};
+struct U {
+ constexpr U SelfReturn();
+ constexpr int SelfParam(U);
+};
+
+struct V : virtual U { // expected-note {{here}}
+ constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
+};
+
+// or a compound-statememt that contains only
+constexpr int AllowedStmts() {
+ // - null statements
+ ;
+
+ // - static_assert-declarations
+ static_assert(true, "the impossible happened!");
+
+ // - typedef declarations and alias-declarations that do not define classes
+ // or enumerations
+ typedef int I;
+ typedef struct S T;
+ using J = int;
+ using K = int[sizeof(I) + sizeof(J)];
+ // Note, the standard requires we reject this.
+ struct U;
+
+ // - using-declarations
+ using N::C;
+
+ // - using-directives
+ using namespace N;
+
+ // - and exactly one return statement
+ return sizeof(K) + sizeof(C) + sizeof(K);
+}
+constexpr int ForStmt() {
+ for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}}
+ return 0;
+}
+constexpr int VarDecl() {
+ constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}}
+ return 0;
+}
+constexpr int FuncDecl() {
+ constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}}
+ return ForwardDecl(42);
+}
+constexpr int ClassDecl1() {
+ typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}}
+ return 0;
+}
+constexpr int ClassDecl2() {
+ using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}}
+ return 0;
+}
+constexpr int ClassDecl3() {
+ struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}}
+ return 0;
+}
+constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
+constexpr int MultiReturn() {
+ return 0; // expected-note {{return statement}}
+ return 0; // expected-error {{multiple return statements in constexpr function}}
+}
+
+// - every constructor call and implicit conversion used in initializing the
+// return value shall be one of those allowed in a constant expression.
+//
+// We implement the proposed resolution of DR1364 and ignore this bullet.
+// However, we implement the spirit of the check as part of the p5 checking that
+// a constexpr function must be able to produce a constant expression.
+namespace DR1364 {
+ constexpr int f(int k) {
+ return k; // ok, even though lvalue-to-rvalue conversion of a function
+ // parameter is not allowed in a constant expression.
+ }
+ int kGlobal; // expected-note {{here}}
+ constexpr int f() { // expected-error {{constexpr function never produces a constant expression}}
+ return kGlobal; // expected-note {{read of non-const}}
+ }
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
new file mode 100644
index 0000000..65573c7
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -0,0 +1,249 @@
+// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s
+
+namespace N {
+ typedef char C;
+}
+
+namespace M {
+ typedef double D;
+}
+
+struct NonLiteral { // expected-note 2{{no constexpr constructors}}
+ NonLiteral() {}
+ NonLiteral(int) {}
+};
+struct Literal {
+ constexpr Literal() {}
+ explicit Literal(int); // expected-note 2 {{here}}
+ operator int() const { return 0; }
+};
+
+// In the definition of a constexpr constructor, each of the parameter types
+// shall be a literal type.
+struct S {
+ constexpr S(int, N::C) {}
+ constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
+ constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
+
+ // In addition, either its function-body shall be = delete or = default
+ constexpr S() = default;
+ constexpr S(Literal) = delete;
+};
+
+// or it shall satisfy the following constraints:
+
+// - the class shall not have any virtual base classes;
+struct T : virtual S { // expected-note {{here}}
+ constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
+};
+namespace IndirectVBase {
+ struct A {};
+ struct B : virtual A {}; // expected-note {{here}}
+ class C : public B {
+ public:
+ constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}}
+ };
+}
+
+// - its function-body shall not be a function-try-block;
+struct U {
+ constexpr U()
+ try // expected-error {{function try block not allowed in constexpr constructor}}
+ : u() {
+ } catch (...) {
+ throw;
+ }
+ int u;
+};
+
+// - the compound-statememt of its function-body shall contain only
+struct V {
+ constexpr V() {
+ // - null statements,
+ ;
+
+ // - static_assert-declarations,
+ static_assert(true, "the impossible happened!");
+
+ // - typedef declarations and alias-declarations that do not define classes
+ // or enumerations,
+ typedef int I;
+ typedef struct S T;
+ using J = int;
+ using K = int[sizeof(I) + sizeof(J)];
+ // Note, the standard requires we reject this.
+ struct U;
+
+ // - using-declarations,
+ using N::C;
+
+ // - and using-directives;
+ using namespace N;
+ }
+
+ constexpr V(int(&)[1]) {
+ for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}}
+ /**/;
+ }
+ constexpr V(int(&)[2]) {
+ constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}}
+ }
+ constexpr V(int(&)[3]) {
+ constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}}
+ }
+ constexpr V(int(&)[4]) {
+ typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}}
+ }
+ constexpr V(int(&)[5]) {
+ using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}}
+ }
+ constexpr V(int(&)[6]) {
+ struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}}
+ }
+ constexpr V(int(&)[7]) {
+ return; // expected-error {{statement not allowed in constexpr constructor}}
+ }
+};
+
+// - every non-static data member and base class sub-object shall be initialized
+struct W {
+ int n; // expected-note {{member not initialized by constructor}}
+ constexpr W() {} // expected-error {{constexpr constructor must initialize all members}}
+};
+struct AnonMembers {
+ int a; // expected-note {{member not initialized by constructor}}
+ union { // expected-note 2{{member not initialized by constructor}}
+ char b;
+ struct {
+ double c;
+ long d; // expected-note {{member not initialized by constructor}}
+ };
+ union {
+ char e;
+ void *f;
+ };
+ };
+ struct { // expected-note {{member not initialized by constructor}}
+ long long g;
+ struct {
+ int h; // expected-note {{member not initialized by constructor}}
+ double i; // expected-note {{member not initialized by constructor}}
+ };
+ union { // expected-note 2{{member not initialized by constructor}}
+ char *j;
+ AnonMembers *k;
+ };
+ };
+
+ constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok
+ // missing d, i, j/k union
+ constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} // expected-error {{constexpr constructor must initialize all members}}
+ constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok
+ // missing h, j/k union
+ constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} // expected-error {{constexpr constructor must initialize all members}}
+ // missing b/c/d/e/f union
+ constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} // expected-error {{constexpr constructor must initialize all members}}
+ // missing a, b/c/d/e/f union, g/h/i/j/k struct
+ constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}}
+};
+
+union Empty {
+ constexpr Empty() {} // ok
+} constexpr empty1;
+
+struct EmptyVariant {
+ union {};
+ struct {};
+ constexpr EmptyVariant() {} // ok
+} constexpr empty2;
+
+template<typename T> using Int = int;
+template<typename T>
+struct TemplateInit {
+ T a;
+ int b; // desired-note {{not initialized}}
+ Int<T> c; // desired-note {{not initialized}}
+ struct {
+ T d;
+ int e; // desired-note {{not initialized}}
+ Int<T> f; // desired-note {{not initialized}}
+ };
+ struct {
+ Literal l;
+ Literal m;
+ Literal n[3];
+ };
+ union { // desired-note {{not initialized}}
+ T g;
+ T h;
+ };
+ // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
+ constexpr TemplateInit() {} // desired-error {{must initialize all members}}
+};
+template<typename T> struct TemplateInit2 {
+ Literal l;
+ constexpr TemplateInit2() {} // ok
+};
+
+template<typename T> struct weak_ptr {
+ constexpr weak_ptr() : p(0) {}
+ T *p;
+};
+template<typename T> struct enable_shared_from_this {
+ weak_ptr<T> weak_this;
+ constexpr enable_shared_from_this() {} // ok
+};
+constexpr int f(enable_shared_from_this<int>);
+
+// - every constructor involved in initializing non-static data members and base
+// class sub-objects shall be a constexpr constructor.
+struct ConstexprBaseMemberCtors : Literal {
+ Literal l;
+
+ constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok
+ constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}}
+ Literal(0), // expected-note {{non-constexpr constructor}}
+ l() {}
+ constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}}
+ l(0) // expected-note {{non-constexpr constructor}}
+ {}
+};
+
+// - every assignment-expression that is an initializer-caluse appearing
+// directly or indirectly within a brace-or-equal-initializer for a non-static
+// data member that is not named by a mem-initializer-id shall be a constant
+// expression; and
+//
+// Note, we deliberately do not implement this bullet, so that we can allow the
+// following example. (See N3308).
+struct X {
+ int a = 0;
+ int b = 2 * a + 1; // ok, not a constant expression.
+
+ constexpr X() {}
+ constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1
+};
+
+// - every implicit conversion used in converting a constructor argument to the
+// corresponding parameter type and converting a full-expression to the
+// corresponding member type shall be one of those allowed in a constant
+// expression.
+//
+// We implement the proposed resolution of DR1364 and ignore this bullet.
+// However, we implement the intent of this wording as part of the p5 check that
+// the function must be able to produce a constant expression.
+int kGlobal; // expected-note {{here}}
+struct Z {
+ constexpr Z(int a) : n(a) {}
+ constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}
+ int n;
+};
+
+
+namespace StdExample {
+ struct Length {
+ explicit constexpr Length(int i = 0) : val(i) { }
+ private:
+ int val;
+ };
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
new file mode 100644
index 0000000..fd17d35
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s
+
+namespace StdExample {
+
+constexpr int f(void *) { return 0; }
+constexpr int f(...) { return 1; }
+constexpr int g1() { return f(0); }
+constexpr int g2(int n) { return f(n); }
+constexpr int g3(int n) { return f(n*0); }
+
+namespace N {
+ constexpr int c = 5;
+ constexpr int h() { return c; }
+}
+constexpr int c = 0;
+constexpr int g4() { return N::h(); }
+
+static_assert(f(0) == 0, "");
+static_assert(f('0') == 1, "");
+static_assert(g1() == 0, "");
+static_assert(g2(0) == 1, "");
+static_assert(g2(1) == 1, "");
+static_assert(g3(0) == 1, "");
+static_assert(g3(1) == 1, "");
+static_assert(N::h() == 5, "");
+static_assert(g4() == 5, "");
+
+
+constexpr int f(bool b)
+ { return b ? throw 0 : 0; } // ok
+constexpr int f() { return throw 0, 0; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{subexpression}}
+
+struct B {
+ constexpr B(int x) : i(0) { }
+ int i;
+};
+
+int global; // expected-note {{declared here}}
+
+struct D : B {
+ constexpr D() : B(global) { } // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}
+};
+
+}
+
+namespace PotentialConstant {
+
+constexpr int Comma(int n) { return // expected-error {{constexpr function never produces a constant expression}}
+ (void)(n * 2),
+ throw 0, // expected-note {{subexpression}}
+ 0;
+}
+
+int ng; // expected-note 6{{here}}
+constexpr int BinaryOp1(int n) { return n + ng; } // expected-error {{never produces}} expected-note {{read}}
+constexpr int BinaryOp2(int n) { return ng + n; } // expected-error {{never produces}} expected-note {{read}}
+
+double dg; // expected-note 2{{here}}
+constexpr double BinaryOp1(double d) { return d + dg; } // expected-error {{never produces}} expected-note {{read}}
+constexpr double BinaryOp2(double d) { return dg + d; } // expected-error {{never produces}} expected-note {{read}}
+
+constexpr int Add(int a, int b, int c) { return a + b + c; }
+constexpr int FunctionArgs(int a) { return Add(a, ng, a); } // expected-error {{never produces}} expected-note {{read}}
+
+struct S { int a; int b; int c[2]; };
+constexpr S InitList(int a) { return { a, ng }; }; // expected-error {{never produces}} expected-note {{read}}
+constexpr S InitList1a(int a) { return S{ a, ng }; }; // expected-error {{never produces}} expected-note {{read}}
+constexpr S InitList2(int a) { return { a, a, { ng } }; }; // expected-error {{never produces}} expected-note {{read}}
+constexpr S InitList3(int a) { return a ? S{ a, a } : S{ a, ng }; }; // ok
+
+constexpr int LogicalAnd1(int n) { return n && (throw, 0); } // ok
+constexpr int LogicalAnd2(int n) { return 1 && (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
+
+constexpr int LogicalOr1(int n) { return n || (throw, 0); } // ok
+constexpr int LogicalOr2(int n) { return 0 || (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
+
+constexpr int Conditional1(bool b, int n) { return b ? n : ng; } // ok
+constexpr int Conditional2(bool b, int n) { return b ? n * ng : n + ng; } // expected-error {{never produces}} expected-note {{both arms of conditional operator are unable to produce a constant expression}}
+
+// __builtin_constant_p ? : is magical, and is always a potential constant.
+constexpr bool BcpCall(int n) {
+ return __builtin_constant_p((int*)n != &n) ? (int*)n != &n : (int*)n != &n;
+}
+static_assert(BcpCall(0), "");
+
+// DR1311: A function template which can produce a constant expression, but
+// for which a particular specialization cannot, is ok.
+template<typename T> constexpr T cmin(T a, T b) {
+ return a < b ? a : b;
+}
+int n = cmin(3, 5); // ok
+
+struct X {
+ constexpr X() {}
+ bool operator<(X); // not constexpr
+};
+
+X x = cmin(X(), X()); // ok, not constexpr
+
+// Same with other temploids.
+template<typename T>
+struct Y {
+ constexpr Y() {}
+ constexpr int get() { return T(); }
+};
+struct Z { operator int(); };
+
+int y1 = Y<int>().get(); // ok
+int y2 = Y<Z>().get(); // ok
+
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
new file mode 100644
index 0000000..1a6dc9e
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+
+namespace N {
+ typedef char C;
+}
+
+namespace M {
+ typedef double D;
+}
+
+struct NonLiteral {
+ NonLiteral() {}
+ NonLiteral(int) {} // expected-note 2{{here}}
+ operator int() const { return 0; }
+};
+struct Literal {
+ constexpr Literal() {}
+ operator int() const { return 0; }
+};
+
+struct S {
+ virtual int ImplicitlyVirtual() const;
+};
+struct T {};
+
+template<typename T> struct ImplicitVirtualFromDependentBase : T {
+ constexpr int ImplicitlyVirtual() { return 0; }
+};
+
+constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}}
+constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // ok
+constexpr int c = ImplicitVirtualFromDependentBase<S>().ImplicitVirtualFromDependentBase<S>::ImplicitlyVirtual();
+
+template<typename R> struct ConstexprMember {
+ constexpr R F() { return 0; }
+};
+constexpr int d = ConstexprMember<int>().F(); // ok
+constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}}
+
+template<typename ...P> struct ConstexprCtor {
+ constexpr ConstexprCtor(P...) {}
+};
+constexpr ConstexprCtor<> f1() { return {}; } // ok
+constexpr ConstexprCtor<int> f2() { return 0; } // ok
+constexpr ConstexprCtor<NonLiteral> f3() { return { 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}}
+constexpr ConstexprCtor<int, NonLiteral> f4() { return { 0, 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}}
+
+struct VirtBase : virtual S {}; // expected-note {{here}}
+
+namespace TemplateVBase {
+ template<typename T> struct T1 : virtual Literal { // expected-note {{here}}
+ constexpr T1() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
+ };
+
+ template<typename T> struct T2 : virtual T {
+ // FIXME: This is ill-formed (no diagnostic required).
+ // We should diagnose it now rather than waiting until instantiation.
+ constexpr T2() {}
+ };
+ constexpr T2<Literal> g2() { return {}; }
+
+ template<typename T> class T3 : public T { // expected-note {{class with virtual base class is not a literal type}}
+ public:
+ constexpr T3() {}
+ };
+ constexpr T3<Literal> g3() { return {}; } // ok
+ constexpr T3<VirtBase> g4() { return {}; } // expected-error {{not a literal type}}
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
new file mode 100644
index 0000000..c4935b3
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct S {
+ constexpr int f();
+ constexpr int g() const;
+ static constexpr int Sf();
+};
+
+void f(const S &s) {
+ s.f();
+ s.g();
+
+ int (*f)() = &S::Sf;
+ int (S::*g)() const = &S::g;
+}
+
+namespace std_example {
+
+ class debug_flag { // expected-note {{not an aggregate and has no constexpr constructors}}
+ public:
+ explicit debug_flag(bool);
+ constexpr bool is_on(); // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}}
+ private:
+ bool flag;
+ };
+
+ constexpr int bar(int x, int y) // expected-note {{here}}
+ { return x + y + x*y; }
+ int bar(int x, int y) // expected-error {{non-constexpr declaration of 'bar' follows constexpr declaration}}
+ { return x * 2 + 3 * y; }
+
+}
+
+// The constexpr specifier is allowed for static member functions of non-literal types.
+class NonLiteralClass {
+ NonLiteralClass(bool);
+ static constexpr bool isDebugFlag();
+};
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
new file mode 100644
index 0000000..2412a14
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// A constexpr specifier used in an object declaration declares the object as
+// const.
+constexpr int a = 0;
+extern const int a;
+
+int i; // expected-note 2{{here}}
+constexpr int *b = &i;
+extern int *const b;
+
+constexpr int &c = i;
+extern int &c;
+
+constexpr int (*d)(int) = 0;
+extern int (*const d)(int);
+
+// A variable declaration which uses the constexpr specifier shall have an
+// initializer and shall be initialized by a constant expression.
+constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}}
+constexpr struct C { C(); } ni2; // expected-error {{cannot have non-literal type 'const struct C'}} expected-note 3{{has no constexpr constructors}}
+constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}}
+
+constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
+constexpr C nc2 = C(); // expected-error {{cannot have non-literal type 'const C'}}
+int &f(); // expected-note {{declared here}}
+constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}}
+constexpr int nc4(i); // expected-error {{constexpr variable 'nc4' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
+constexpr C nc5((C())); // expected-error {{cannot have non-literal type 'const C'}}
+int &f(); // expected-note {{here}}
+constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}}
+
+struct pixel {
+ int x, y;
+};
+constexpr pixel ur = { 1294, 1024 }; // ok
+constexpr pixel origin; // expected-error {{default initialization of an object of const type 'const pixel' requires a user-provided default constructor}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp
new file mode 100644
index 0000000..d7b9eff
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -verify %s
+
+void f0a(void) {
+ inline void f1(); // expected-error {{inline declaration of 'f1' not allowed in block scope}}
+}
+
+void f0b(void) {
+ void f1();
+}
+
+// FIXME: Add test for "If the inline specifier is used in a friend declaration,
+// that declaration shall be a definition or the function shall have previously
+// been declared inline.
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
new file mode 100644
index 0000000..07eec1e
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -verify %s
+// XFAIL: *
+
+void f0() {
+}
+
+inline void f0(); // expected-error {{function definition cannot precede inline declaration}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
new file mode 100644
index 0000000..ee870d9
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify %s
+
+class A {
+public:
+ explicit A();
+
+ explicit operator int(); // expected-warning {{explicit conversion functions are a C++11 extension}}
+
+ explicit void f0(); // expected-error {{'explicit' can only be applied to a constructor or conversion function}}
+
+ operator bool();
+};
+
+explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}}
+explicit A::operator bool() { return false; } // expected-warning {{explicit conversion functions are a C++11 extension}}\
+ // expected-error {{'explicit' can only be specified inside the class definition}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
new file mode 100644
index 0000000..cbb439e
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A storage-class-specifier shall not be specified in an explicit
+// specialization (14.7.3) or an explicit instantiation (14.7.2)
+// directive.
+template<typename T> void f(T) {}
+template<typename T> static void g(T) {}
+
+
+template<> static void f<int>(int); // expected-error{{explicit specialization has extraneous, inconsistent storage class 'static'}}
+template static void f<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
+
+template<> void f<double>(double);
+template void f<long>(long);
+
+template<> static void g<int>(int); // expected-warning{{explicit specialization cannot have a storage class}}
+template static void g<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
+
+template<> void g<double>(double);
+template void g<long>(long);
+
+template<typename T>
+struct X {
+ static int value;
+};
+
+template<typename T>
+int X<T>::value = 17;
+
+template static int X<int>::value; // expected-error{{explicit instantiation cannot have a storage class}}
+
+template<> static int X<float>::value; // expected-error{{'static' can only be specified inside the class definition}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
new file mode 100644
index 0000000..fd86276
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify %s
+// XFAIL: *
+
+typedef const int T0;
+typedef int& T1;
+
+struct s0 {
+ mutable const int f0; // expected-error{{'mutable' and 'const' cannot be mixed}}
+ mutable T0 f1; // expected-error{{'mutable' and 'const' cannot be mixed}}
+ mutable int &f2; // expected-error{{'mutable' cannot be applied to references}}
+ mutable T1 f3; // expected-error{{'mutable' cannot be applied to references}}
+ mutable struct s1 {}; // expected-error{{'mutable' cannot be applied to non-data members}}
+ mutable void im0(); // expected-error{{'mutable' cannot be applied to functions}}
+};
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
new file mode 100644
index 0000000..44cc5a7
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-compat %s
+
+// The auto or register specifiers can be applied only to names of objects
+// declared in a block (6.3) or to function parameters (8.4).
+
+auto int ao; // expected-error {{illegal storage class on file-scoped variable}}
+auto void af(); // expected-error {{illegal storage class on function}}
+
+register int ro; // expected-error {{illegal storage class on file-scoped variable}}
+register void rf(); // expected-error {{illegal storage class on function}}
+
+struct S {
+ auto int ao; // expected-error {{storage class specified for a member declaration}}
+ auto void af(); // expected-error {{storage class specified for a member declaration}}
+
+ register int ro; // expected-error {{storage class specified for a member declaration}}
+ register void rf(); // expected-error {{storage class specified for a member declaration}}
+};
+
+void foo(auto int ap, register int rp) {
+ auto int abo;
+ auto void abf(); // expected-error {{illegal storage class on function}}
+
+ register int rbo;
+ register void rbf(); // expected-error {{illegal storage class on function}}
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
new file mode 100644
index 0000000..491ab17
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -verify %s
+
+struct S; // expected-note 2{{forward declaration of 'S'}}
+extern S a;
+extern S f(); // expected-note {{'f' declared here}}
+extern void g(S a);
+
+void h() {
+ g(a); // expected-error {{argument type 'S' is incomplete}}
+ f(); // expected-error {{calling 'f' with incomplete return type 'S'}}
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp
new file mode 100644
index 0000000..a385aa9
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s -std=c++11
+
+struct S {
+ virtual ~S();
+
+ void g() throw (auto(*)()->int);
+
+ // Note, this is not permitted: conversion-declarator cannot have a trailing return type.
+ // FIXME: don't issue the second diagnostic for this.
+ operator auto(*)()->int(); // expected-error{{'auto' not allowed here}} expected-error {{C++ requires a type specifier}}
+};
+
+typedef auto Fun(int a) -> decltype(a + a);
+typedef auto (*PFun)(int a) -> decltype(a + a);
+
+void g(auto (*f)() -> int) {
+ try { }
+ catch (auto (&f)() -> int) { }
+ catch (auto (*const f[10])() -> int) { }
+}
+
+namespace std {
+ class type_info;
+}
+
+template<typename T> struct U {};
+
+void j() {
+ (void)typeid(auto(*)()->void);
+ (void)sizeof(auto(*)()->void);
+ (void)__alignof(auto(*)()->void);
+
+ U<auto(*)()->void> v;
+
+ int n;
+ (void)static_cast<auto(*)()->void>(&j);
+ auto p = reinterpret_cast<auto(*)()->int>(&j);
+ (void)const_cast<auto(**)()->int>(&p);
+ (void)(auto(*)()->void)(&j);
+}
+
+template <auto (*f)() -> void = &j> class C { };
+struct F : auto(*)()->int {}; // expected-error{{expected class name}}
+template<typename T = auto(*)()->int> struct G { };
+
+int g();
+auto (*h)() -> auto = &g; // expected-error{{'auto' not allowed in function return type}}
+auto (*i)() = &g; // ok; auto deduced as int.
+auto (*k)() -> int = i; // ok; no deduction.
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
new file mode 100644
index 0000000..1daf02f
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions -Wc++11-compat
+void f() {
+ auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
+ auto *b = b; // expected-error{{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
+ const auto c = c; // expected-error{{variable 'c' declared with 'auto' type cannot appear in its own initializer}}
+ if (auto d = d) {} // expected-error {{variable 'd' declared with 'auto' type cannot appear in its own initializer}}
+ auto e = ({ auto f = e; 0; }); // expected-error {{variable 'e' declared with 'auto' type cannot appear in its own initializer}}
+}
+
+void g() {
+ auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+
+ auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
+
+ if (auto b) {} // expected-error {{must have an initializer}}
+ for (;auto b;) {} // expected-error {{must have an initializer}}
+ while (auto b) {} // expected-error {{must have an initializer}}
+ if (auto b = true) { (void)b; }
+}
+
+auto n(1,2,3); // expected-error{{initializer for variable 'n' with type 'auto' contains multiple expressions}}
+
+namespace N
+{
+ auto a = "const char [16]", *p = &a;
+}
+
+void h() {
+ auto b = 42ULL;
+
+ for (auto c = 0; c < b; ++c) {
+ }
+}
+
+template<typename T, typename U> struct same;
+template<typename T> struct same<T, T> {};
+
+void p3example() {
+ auto x = 5;
+ const auto *v = &x, u = 6;
+ static auto y = 0.0;
+ // In C++98: 'auto' storage class specifier is redundant and incompatible with C++0x
+ // In C++0x: 'auto' storage class specifier is not permitted in C++0x, and will not be supported in future releases
+ auto int r; // expected-warning {{'auto' storage class specifier}}
+
+ same<__typeof(x), int> xHasTypeInt;
+ same<__typeof(v), const int*> vHasTypeConstIntPtr;
+ same<__typeof(u), const int> uHasTypeConstInt;
+ same<__typeof(y), double> yHasTypeDouble;
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
new file mode 100644
index 0000000..e566d2a
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
+
+template<typename T>
+struct only {
+ only(T);
+ template<typename U> only(U) = delete;
+};
+
+void f() {
+ if (auto a = true) {
+ }
+
+ switch (auto a = 0) {
+ }
+
+ while (auto a = false) {
+ }
+
+ for (; auto a = false; ) {
+ }
+
+ new const auto (0);
+ new (auto) (0.0);
+
+ int arr[] = {1, 2, 3};
+ for (auto i : arr) {
+ }
+}
+
+class X {
+ static const auto n = 'x';
+
+ auto m = 0; // expected-error {{'auto' not allowed in non-static class member}}
+};
+
+struct S {
+ static const auto a; // expected-error {{declaration of variable 'a' with type 'auto const' requires an initializer}}
+ static const auto b = 0;
+ static const int c;
+};
+const int S::b;
+const auto S::c = 0;
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
new file mode 100644
index 0000000..71f57dc
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s -std=c++11
+
+struct S {
+ virtual ~S();
+
+ auto a; // expected-error{{'auto' not allowed in non-static struct member}}
+ auto *b; // expected-error{{'auto' not allowed in non-static struct member}}
+ const auto c; // expected-error{{'auto' not allowed in non-static struct member}}
+
+ void f() throw (auto); // expected-error{{'auto' not allowed here}}
+
+ friend auto; // expected-error{{'auto' not allowed in non-static struct member}}
+
+ operator auto(); // expected-error{{'auto' not allowed here}}
+};
+
+// PR 9278: auto is not allowed in typedefs, except with a trailing return type.
+typedef auto *AutoPtr; // expected-error{{'auto' not allowed in typedef}}
+typedef auto (*PFun)(int a); // expected-error{{'auto' not allowed in typedef}}
+typedef auto Fun(int a) -> decltype(a + a);
+
+void g(auto a) { // expected-error{{'auto' not allowed in function prototype}}
+ try { }
+ catch (auto &a) { } // expected-error{{'auto' not allowed in exception declaration}}
+ catch (const auto a) { } // expected-error{{'auto' not allowed in exception declaration}}
+ try { } catch (auto a) { } // expected-error{{'auto' not allowed in exception declaration}}
+}
+
+void h(auto a[10]) { // expected-error{{'auto' not allowed in function prototype}}
+}
+
+void i(const auto a) { // expected-error{{'auto' not allowed in function prototype}}
+}
+
+namespace std {
+ class type_info;
+}
+
+template<typename T> struct U {};
+
+void j() {
+ (void)typeid(auto); // expected-error{{'auto' not allowed here}}
+ (void)sizeof(auto); // expected-error{{'auto' not allowed here}}
+ (void)__alignof(auto); // expected-error{{'auto' not allowed here}}
+
+ U<auto> v; // expected-error{{'auto' not allowed in template argument}}
+
+ int n;
+ (void)dynamic_cast<auto&>(n); // expected-error{{'auto' not allowed here}}
+ (void)static_cast<auto*>(&n); // expected-error{{'auto' not allowed here}}
+ (void)reinterpret_cast<auto*>(&n); // expected-error{{'auto' not allowed here}}
+ (void)const_cast<auto>(n); // expected-error{{'auto' not allowed here}}
+ (void)*(auto*)(&n); // expected-error{{'auto' not allowed here}}
+ (void)auto(n); // expected-error{{expected expression}}
+ (void)auto{n}; // expected-error{{expected expression}}
+}
+
+template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}}
+int ints[] = {1, 2, 3};
+template <const auto (*a)[3] = &ints> class D { }; // expected-error{{'auto' not allowed in template parameter}}
+enum E : auto {}; // expected-error{{'auto' not allowed here}}
+struct F : auto {}; // expected-error{{expected class name}}
+template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed in template argument}}
+
+using A = auto; // expected-error{{'auto' not allowed in type alias}}
+
+// FIXME: don't issue the second diagnostic for this error.
+auto k() -> auto; // expected-error{{'auto' not allowed in function return type}} unexpected-error{{without trailing return type}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
new file mode 100644
index 0000000..d327efc
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
+
+template<typename T>
+struct only {
+ only(T);
+ template<typename U> only(U) = delete;
+};
+
+namespace N
+{
+ auto a = "const char [16]", *p = &a;
+
+ only<const char [16]> testA = a;
+ only<const char **> testP = p;
+}
+
+void h() {
+ auto b = 42ULL;
+ only<unsigned long long> testB = b;
+
+ for (auto c = 0; c < 100; ++c) {
+ only<int> testC = c;
+ }
+}
+
+void p3example() {
+ auto x = 5;
+ const auto *v = &x, u = 6;
+ static auto y = 0.0;
+
+ only<int> testX = x;
+ only<const int*> testV = v;
+ only<const int> testU = u;
+ only<double> testY = y;
+}
+
+void f() {
+ if (auto a = true) {
+ only<bool> testA = a;
+ }
+
+ switch (auto a = 0) {
+ case 0:
+ only<int> testA = a;
+ }
+
+ while (auto a = false) {
+ only<bool> testA = a;
+ }
+
+ for (; auto a = "test"; ) {
+ only<const char[5]> testA = a;
+ }
+
+ auto *fail1 = 0; // expected-error {{variable 'fail1' with type 'auto *' has incompatible initializer of type 'int'}}
+ int **p;
+ const auto **fail2(p); // expected-error {{variable 'fail2' with type 'auto const **' has incompatible initializer of type 'int **'}}
+}
+
+struct S {
+ void f();
+ char g(int);
+ float g(double);
+ int m;
+
+ void test() {
+ auto p1 = &S::f;
+ auto S::*p2 = &S::f;
+ auto (S::*p3)() = &S::f;
+ auto p4 = &S::g; // expected-error {{incompatible initializer of type '<overloaded function type>'}}
+ auto S::*p5 = &S::g; // expected-error {{incompatible initializer of type '<overloaded function type>'}}
+ auto (S::*p6)(int) = &S::g;
+ auto p7 = &S::m;
+ auto S::*p8 = &S::m;
+
+ only<void (S::*)()> test1 = p1;
+ only<void (S::*)()> test2 = p2;
+ only<void (S::*)()> test3 = p3;
+ only<char (S::*)(int)> test6 = p6;
+ only<int (S::*)> test7 = p7;
+ only<int (S::*)> test8 = p8;
+ }
+};
+
+namespace PR10939 {
+ struct X {
+ int method(int);
+ int method(float);
+ };
+
+ template<typename T> T g(T);
+
+ void f(X *x) {
+ auto value = x->method; // expected-error {{reference to non-static member function must be called}}
+ if (value) { }
+
+ auto funcptr = &g<int>;
+ int (*funcptr2)(int) = funcptr;
+ }
+}
+
+// if the initializer is a braced-init-list, deduce auto as std::initializer_list<T>:
+// see SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
new file mode 100644
index 0000000..9c1d397
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
+void f() {
+ auto a = 0, b = 0, c = 0;
+ auto d = 0, e = 0.0; // expected-error {{'int' in declaration of 'd' and deduced as 'double' in declaration of 'e'}}
+
+ auto v1 = 0, *p1 = &v1;
+ auto *p2 = 0, v2 = *p2; // expected-error {{incompatible initializer}}
+
+ const int k = 0;
+ auto &f = k, &g = a; // expected-error {{'const int' in declaration of 'f' and deduced as 'int' in declaration of 'g'}}
+
+ typedef int I;
+ I x;
+ auto xa = x, xb = 0;
+
+ auto &&ra1 = a, rb1 = b; // expected-error {{'int &' in declaration of 'ra1' and deduced as 'int' in declaration of 'rb1'}}
+ auto &&ra2 = +a, rb2 = b;
+}
+
+void g() {
+ auto a = 0,
+#if __has_feature(cxx_trailing_return)
+ (*b)() -> void,
+#endif
+ c = 0;
+ auto d = 0, // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}}
+#if __has_feature(cxx_trailing_return)
+ (*e)() -> void,
+#endif
+ f = 0.0;
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
new file mode 100644
index 0000000..0271041
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+struct A { typedef int type; };
+template<typename T> using X = A; // expected-note {{declared here}}
+struct X<int>* p2; // expected-error {{elaborated type refers to a type alias template}}
+
+
+template<typename T> using Id = T; // expected-note {{declared here}}
+template<template<typename> class F>
+struct Y {
+ struct F<int> i; // expected-error {{elaborated type refers to a type alias template}}
+ typename F<A>::type j; // ok
+
+ // FIXME: don't produce the diagnostic both for the definition and the instantiation.
+ template<typename T> using U = F<char>; // expected-note 2{{declared here}}
+ struct Y<F>::template U<char> k; // expected-error 2{{elaborated type refers to a type alias template}}
+ typename Y<F>::template U<char> l; // ok
+};
+template struct Y<Id>; // expected-note {{requested here}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
new file mode 100644
index 0000000..8d58498
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class A {}; // expected-note 4 {{previous use is here}}
+enum E {};
+
+void a1(struct A);
+void a2(class A);
+void a3(union A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+void a4(enum A); // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+
+class A1 {
+ friend struct A;
+ friend class A;
+ friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+
+ friend enum A; // expected-error {{use of 'A' with tag type that does not match previous declaration}}
+ friend enum E; // expected-warning {{cannot be a friend}}
+};
+
+template <class T> struct B { // expected-note {{previous use is here}}
+ class Member {}; // expected-note 2 {{previous use is here}}
+};
+
+template <> class B<int> {
+ // no type Member
+};
+
+template <> struct B<A> {
+ union Member { // expected-note 4 {{previous use is here}}
+ void* a;
+ };
+};
+
+void b1(struct B<float>);
+void b2(class B<float>);
+void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}}
+//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly
+
+void c1(struct B<float>::Member);
+void c2(class B<float>::Member);
+void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+
+void d1(struct B<int>::Member); // expected-error {{no struct named 'Member' in 'B<int>'}}
+void d2(class B<int>::Member); // expected-error {{no class named 'Member' in 'B<int>'}}
+void d3(union B<int>::Member); // expected-error {{no union named 'Member' in 'B<int>'}}
+void d4(enum B<int>::Member); // expected-error {{no enum named 'Member' in 'B<int>'}}
+
+void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+void e3(union B<A>::Member);
+void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
+
+template <class T> struct C {
+ void foo(class B<T>::Member); // expected-error{{no class named 'Member' in 'B<int>'}} \
+ // expected-error{{use of 'Member' with tag type that does not match previous declaration}}
+};
+
+C<float> f1;
+C<int> f2; // expected-note {{in instantiation of template class}}
+C<A> f3; // expected-note {{in instantiation of template class}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
new file mode 100644
index 0000000..53227ea
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+const int&& foo();
+int i;
+struct A { double x; };
+const A* a = new A();
+
+static_assert(is_same<decltype(foo()), const int&&>::value, "");
+static_assert(is_same<decltype(i), int>::value, "");
+static_assert(is_same<decltype(a->x), double>::value, "");
+static_assert(is_same<decltype((a->x)), const double&>::value, "");
+static_assert(is_same<decltype(static_cast<int&&>(i)), int&&>::value, "");
+
+int f0(int); // expected-note{{possible target}}
+float f0(float); // expected-note{{possible target}}
+
+decltype(f0) f0_a; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
new file mode 100644
index 0000000..2bd5d23
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+namespace std_example {
+
+template<class T> struct A { ~A() = delete; }; // expected-note {{deleted here}}
+template<class T> auto h() -> A<T>;
+template<class T> auto i(T) -> T;
+template<class T> auto f(T) -> decltype(i(h<T>())); // #1
+template<class T> auto f(T) -> void; // #2
+auto g() -> void {
+ f(42); // ok, calls #2, since #1 is not viable.
+}
+template<class T> auto q(T) -> decltype((h<T>()));
+void r() {
+ // Deduction against q succeeds, but results in a temporary which can't be
+ // destroyed.
+ q(42); // expected-error {{attempt to use a deleted function}}
+}
+
+}
+
+class PD {
+ friend struct A;
+ ~PD(); // expected-note 4{{here}}
+public:
+ typedef int n;
+};
+struct DD {
+ ~DD() = delete; // expected-note 2{{here}}
+ typedef int n;
+};
+
+struct A {
+ decltype(PD()) s; // ok
+ decltype(PD())::n n; // ok
+ decltype(DD()) *p = new decltype(DD()); // ok
+};
+
+// Two errors here: one for the decltype, one for the variable.
+decltype(PD(), PD()) pd1; // expected-error 2{{private destructor}}
+decltype(DD(), DD()) dd1; // expected-error 2{{deleted function}}
+
+decltype(((13, ((DD())))))::n dd_parens; // ok
+decltype(((((42)), PD())))::n pd_parens_comma; // ok
+
+// Ensure parens aren't stripped from a decltype node.
+extern decltype(PD()) pd_ref; // ok
+decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD &
+decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}}
+
+namespace libcxx_example {
+ struct nat {
+ nat() = delete;
+ nat(const nat&) = delete;
+ nat &operator=(const nat&) = delete;
+ ~nat() = delete;
+ };
+ struct any {
+ any(...);
+ };
+
+ template<typename T, typename U> struct is_same { static const bool value = false; };
+ template<typename T> struct is_same<T, T> { static const bool value = true; };
+
+ template<typename T> T declval();
+
+ void swap(int &a, int &b);
+ nat swap(any, any);
+
+ template<typename T> struct swappable {
+ typedef decltype(swap(declval<T&>(), declval<T&>())) type;
+ static const bool value = !is_same<type, nat>::value;
+ constexpr operator bool() { return value; }
+ };
+
+ static_assert(swappable<int>(), "");
+ static_assert(!swappable<const int>(), "");
+}
+
+namespace RequireCompleteType {
+ template<int N, bool OK> struct S {
+ static_assert(OK, "boom!"); // expected-error 2{{boom!}}
+ };
+
+ template<typename T> T make();
+ template<int N, bool OK> S<N, OK> make();
+ void consume(...);
+
+ decltype(make<0, false>()) *p1; // ok
+ decltype((make<1, false>())) *p2; // ok
+
+ // A complete type is required here in order to detect an overloaded 'operator,'.
+ decltype(123, make<2, false>()) *p3; // expected-note {{here}}
+
+ decltype(consume(make<3, false>())) *p4; // expected-note {{here}}
+
+ decltype(make<decltype(make<4, false>())>()) *p5; // ok
+}
+
+namespace Overload {
+ DD operator+(PD &a, PD &b);
+ decltype(PD()) *pd_ptr;
+ decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok
+
+ decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok
+ DD operator,(int a, PD b);
+ decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}}
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
new file mode 100644
index 0000000..0b518bb
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fcxx-exceptions
+
+using X = struct { // ok
+};
+template<typename T> using Y = struct { // expected-error {{can not be defined in a type alias template}}
+};
+
+class K {
+ virtual ~K();
+ operator struct S {} (); // expected-error{{'K::S' can not be defined in a type specifier}}
+};
+
+struct A {};
+
+void f() {
+ int arr[3] = {1,2,3};
+
+ for (struct S { S(int) {} } s : arr) { // expected-error {{types may not be defined in a for range declaration}}
+ }
+
+ new struct T {}; // expected-error {{'T' can not be defined in a type specifier}}
+ new struct A {}; // expected-error {{'A' can not be defined in a type specifier}}
+
+ try {} catch (struct U {}) {} // expected-error {{'U' can not be defined in a type specifier}}
+
+ (void)(struct V { V(int); })0; // expected-error {{'V' can not be defined in a type specifier}}
+
+ (void)dynamic_cast<struct W {}*>((K*)0); // expected-error {{'W' can not be defined in a type specifier}}
+ (void)static_cast<struct X {}*>(0); // expected-error {{'X' can not be defined in a type specifier}}
+ (void)reinterpret_cast<struct Y {}*>(0); // expected-error {{'Y' can not be defined in a type specifier}}
+ (void)const_cast<struct Z {}*>((const Z*)0); // expected-error {{'Z' can not be defined in a type specifier}}
+}
+
+void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}}
+}
+
+int alignas(struct Aa {}) x; // expected-error {{'Aa' can not be defined in a type specifier}}
+
+int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}}
+int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}}
+
+namespace std { struct type_info; }
+const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' can not be defined in a type specifier}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
new file mode 100644
index 0000000..b06eb01
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
@@ -0,0 +1,160 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+
+namespace RedeclAliasTypedef {
+ typedef int T;
+ using T = int;
+ using T = int;
+ typedef T T;
+ using T = T;
+ typedef int T;
+}
+
+namespace IllegalTypeIds {
+ using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}}
+ using B = inline void(int n); // expected-error {{type name does not allow function specifier}}
+ using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
+ using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
+ using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
+ using F = void(*)(int n) &&; // expected-error {{pointer to function type cannot have '&&' qualifier}}
+ using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}
+ using H = constexpr int; // expected-error {{type name does not allow constexpr specifier}}
+
+ using Y = void(int n); // ok
+ using Z = void(int n) &&; // ok
+}
+
+namespace IllegalSyntax {
+ using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
+ using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+}
+
+namespace VariableLengthArrays {
+ using T = int[42]; // ok
+
+ int n = 32;
+ using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+ const int m = 42;
+ using U = int[m]; // expected-note {{previous definition}}
+ using U = int[42]; // ok
+ using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}}
+
+ void f() {
+ int n = 42;
+ goto foo; // expected-error {{goto into protected scope}}
+ using T = int[n]; // expected-note {{bypasses initialization of VLA type alias}}
+ foo: ;
+ }
+}
+
+namespace RedeclFunc {
+ int f(int, char**);
+ using T = int;
+ T f(int, char **); // ok
+}
+
+namespace LookupFilter {
+ namespace N { struct S; }
+ using namespace N;
+ using S = S*; // ok
+}
+
+namespace InFunctions {
+ template<typename...T> void f0() {
+ using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+ U u;
+ }
+ template void f0<int, char>();
+
+ void f1() {
+ using T = int;
+ }
+ void f2() {
+ using T = int[-1]; // expected-error {{array size is negative}}
+ }
+
+ template<typename...T> void f3() { // expected-note {{template parameter is declared here}}
+ using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ }
+}
+
+namespace ClassNameRedecl {
+ class C0 {
+ // FIXME: this diagnostic is pretty poor
+ using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}}
+ };
+ class C1 {
+ // FIXME: this diagnostic is pretty poor
+ using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}}
+ };
+ class C2 {
+ using C0 = C1; // ok
+ };
+ template<typename...T> class C3 {
+ using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+ };
+ template<typename T> class C4 { // expected-note {{template parameter is declared here}}
+ using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ class C5 {
+ class c; // expected-note {{previous definition}}
+ using c = int; // expected-error {{typedef redefinition with different types}}
+ class d;
+ using d = d; // ok
+ };
+ class C6 {
+ class c { using C6 = int; }; // ok
+ };
+}
+
+class CtorDtorName {
+ using X = CtorDtorName;
+ X(); // expected-error {{expected member name}}
+ ~X(); // expected-error {{destructor cannot be declared using a type alias}}
+};
+
+namespace TagName {
+ using S = struct { int n; };
+ using T = class { int n; };
+ using U = enum { a, b, c };
+ using V = struct V { int n; };
+}
+
+namespace CWG1044 {
+ // FIXME: this diagnostic isn't ideal. one diagnostic is enough.
+ using T = T; // expected-error {{type name requires a specifier}} \
+ expected-error {{expected ';' after alias declaration}}
+}
+
+namespace StdExample {
+ template<typename T, typename U> struct pair;
+
+ using handler_t = void (*)(int);
+ extern handler_t ignore;
+ extern void (*ignore)(int);
+ // FIXME: we know we're parsing a type here; don't recover as if we were
+ // using operator*.
+ using cell = pair<void*, cell*>; // expected-error {{use of undeclared identifier 'cell'}} \
+ expected-error {{expected expression}}
+}
+
+namespace Access {
+ class C0 {
+ using U = int; // expected-note {{declared private here}}
+ };
+ C0::U v; // expected-error {{'U' is a private member}}
+ class C1 {
+ public:
+ using U = int;
+ };
+ C1::U w; // ok
+}
+
+namespace VoidArg {
+ using V = void;
+ V f(int); // ok
+ V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp
new file mode 100644
index 0000000..28f49d0
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify %s
+
+typedef struct s { int x; } s;
+typedef int I;
+typedef int I2;
+typedef I2 I; // expected-note {{previous definition is here}}
+
+typedef char I; // expected-error {{typedef redefinition with different types}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp
new file mode 100644
index 0000000..c16ba20
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify %s
+
+struct S {
+ typedef struct A {} A; // expected-note {{previous definition is here}}
+ typedef struct B B;
+ typedef A A; // expected-error {{redefinition of 'A'}}
+
+ struct C { };
+ typedef struct C OtherC;
+ typedef OtherC C;
+
+ typedef struct D { } D2;
+ typedef D2 D;
+};
+