Final piece of core issue 1330: delay computing the exception specification of
a defaulted special member function until the exception specification is needed
(using the same criteria used for the delayed instantiation of exception
specifications for function temploids).

EST_Delayed is now EST_Unevaluated (using 1330's terminology), and, like
EST_Uninstantiated, carries a pointer to the FunctionDecl which will be used to
resolve the exception specification.

This is enabled for all C++ modes: it's a little faster in the case where the
exception specification isn't used, allows our C++11-in-C++98 extensions to
work, and is still correct for C++98, since in that mode the computation of the
exception specification can't fail.

The diagnostics here aren't great (in particular, we should include implicit
evaluation of exception specifications for defaulted special members in the
template instantiation backtraces), but they're not much worse than before.

Our approach to the problem of cycles between in-class initializers and the
exception specification for a defaulted default constructor is modified a
little by this change -- we now reject any odr-use of a defaulted default
constructor if that constructor uses an in-class initializer and the use is in
an in-class initialzer which is declared lexically earlier. This is a closer
approximation to the current draft solution in core issue 1351, but isn't an
exact match (but the current draft wording isn't reasonable, so that's to be
expected).

llvm-svn: 160847
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp
index 15efb48..21f71f0 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp
@@ -4,9 +4,11 @@
 // [...]
 //   -- not have default arguments
 struct DefArg {
+  static DefArg &&make();
   DefArg(int n = 5) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
-  DefArg(const DefArg &DA = DefArg(2)) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
+  DefArg(const DefArg &DA = make()) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
   DefArg(const DefArg &DA, int k = 3) = default; // expected-error {{an explicitly-defaulted copy constructor cannot have default arguments}}
+  DefArg(DefArg &&DA = make()) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
   DefArg(DefArg &&DA, int k = 3) = default; // expected-error {{an explicitly-defaulted move constructor cannot have default arguments}}
   DefArg &operator=(const DefArg&, int k = 4) = default; // expected-error {{parameter of overloaded 'operator=' cannot have a default argument}}
   DefArg &operator=(DefArg&&, int k = 4) = default; // expected-error {{parameter of overloaded 'operator=' cannot have a default argument}}
diff --git a/clang/test/CodeGenCXX/member-init-ctor.cpp b/clang/test/CodeGenCXX/member-init-ctor.cpp
deleted file mode 100644
index 2172394..0000000
--- a/clang/test/CodeGenCXX/member-init-ctor.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
-
-bool b();
-struct S {
-  int n = b() ? S().n + 1 : 0;
-};
-
-S s;
-
-// CHECK: define {{.*}} @_ZN1SC2Ev(
-// CHECK-NOT }
-// CHECK: call {{.*}} @_Z1bv()
-// CHECK-NOT }
-// CHECK: call {{.*}} @_ZN1SC1Ev(
diff --git a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 595d428..61c4c33 100644
--- a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -57,3 +57,63 @@
   friend S<bar>::S(const S&);
   friend S<bar>::S(S&&);
 };
+
+namespace DefaultedFnExceptionSpec {
+  // DR1330: The exception-specification of an implicitly-declared special
+  // member function is evaluated as needed.
+  template<typename T> T &&declval();
+  template<typename T> struct pair {
+    pair(const pair&) noexcept(noexcept(T(declval<T>())));
+  };
+
+  struct Y;
+  struct X { X(); X(const Y&); };
+  struct Y { pair<X> p; };
+
+  template<typename T>
+  struct A {
+    pair<T> p;
+  };
+  struct B {
+    B();
+    B(const A<B>&);
+  };
+
+  // Don't crash here.
+  void f() {
+    X x = X();
+    (void)noexcept(B(declval<B>()));
+  }
+
+  template<typename T>
+  struct Error {
+    // FIXME: Type canonicalization causes all the errors to point at the first
+    // declaration which has the type 'void () noexcept (T::error)'. We should
+    // get one error for 'Error<int>::Error()' and one for 'Error<int>::~Error()'.
+    void f() noexcept(T::error); // expected-error 2{{has no members}}
+
+    Error() noexcept(T::error);
+    Error(const Error&) noexcept(T::error);
+    Error(Error&&) noexcept(T::error);
+    Error &operator=(const Error&) noexcept(T::error);
+    Error &operator=(Error&&) noexcept(T::error);
+    ~Error() noexcept(T::error);
+  };
+
+  struct DelayImplicit {
+    Error<int> e;
+  };
+
+  // Don't instantiate the exception specification here.
+  void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit())));
+  void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>()));
+  void test3(decltype(DelayImplicit(declval<const DelayImplicit>())));
+
+  // Any odr-use causes the exception specification to be evaluated.
+  struct OdrUse { // \
+    expected-note {{instantiation of exception specification for 'Error'}} \
+    expected-note {{instantiation of exception specification for '~Error'}}
+    Error<int> e;
+  };
+  OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}}
+}
diff --git a/clang/test/SemaCXX/implicit-exception-spec.cpp b/clang/test/SemaCXX/implicit-exception-spec.cpp
index 25316f8..b29cff5 100644
--- a/clang/test/SemaCXX/implicit-exception-spec.cpp
+++ b/clang/test/SemaCXX/implicit-exception-spec.cpp
@@ -17,7 +17,7 @@
   // is false.
   bool ThrowSomething() noexcept(false);
   struct ConstExpr {
-    bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{exception specification is not available until end of class definition}}
+    bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot be used by non-static data member initializer}}
   };
   // We can use it now.
   bool w = noexcept(ConstExpr());
@@ -25,18 +25,27 @@
   // Much more obviously broken: we can't parse the initializer without already
   // knowing whether it produces a noexcept expression.
   struct TemplateArg {
-    int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{exception specification is not available until end of class definition}}
+    int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot be used by non-static data member initializer}}
   };
   bool x = noexcept(TemplateArg());
 
   // And within a nested class.
+  // FIXME: The diagnostic location is terrible here.
   struct Nested {
     struct Inner {
-      int n = ExceptionIf<noexcept(Nested())>::f(); // expected-error {{exception specification is not available until end of class definition}}
-    } inner;
+      int n = ExceptionIf<noexcept(Nested())>::f();
+    } inner; // expected-error {{cannot be used by non-static data member initializer}}
   };
   bool y = noexcept(Nested());
   bool z = noexcept(Nested::Inner());
+
+  struct Nested2 {
+    struct Inner;
+    int n = Inner().n; // expected-error {{cannot be used by non-static data member initializer}}
+    struct Inner {
+      int n = ExceptionIf<noexcept(Nested())>::f();
+    } inner;
+  };
 }
 
 namespace ExceptionSpecification {
diff --git a/clang/test/SemaCXX/member-init.cpp b/clang/test/SemaCXX/member-init.cpp
index 3ca41a0..a13941f 100644
--- a/clang/test/SemaCXX/member-init.cpp
+++ b/clang/test/SemaCXX/member-init.cpp
@@ -14,7 +14,7 @@
 bool b();
 int k;
 struct Recurse {
-  int &n = b() ? Recurse().n : k; // ok
+  int &n = b() ? Recurse().n : k; // expected-error {{defaulted default constructor of 'Recurse' cannot be used by non-static data member initializer which appears before end of class definition}}
 };
 
 struct UnknownBound {
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 63286e6..bf590f9 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1384,9 +1384,6 @@
   { int arr[F(__has_nothrow_copy(cvoid))]; }
 }
 
-template<bool b> struct assert_expr;
-template<> struct assert_expr<true> {};
-
 void has_nothrow_constructor() {
   { int arr[T(__has_nothrow_constructor(Int))]; }
   { int arr[T(__has_nothrow_constructor(IntAr))]; }
@@ -1415,11 +1412,6 @@
   { int arr[F(__has_nothrow_constructor(void))]; }
   { int arr[F(__has_nothrow_constructor(cvoid))]; }
   { int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
-
-  // While parsing an in-class initializer, the constructor is not known to be
-  // non-throwing yet.
-  struct HasInClassInit { int n = (assert_expr<!__has_nothrow_constructor(HasInClassInit)>(), 0); };
-  { int arr[T(__has_nothrow_constructor(HasInClassInit))]; }
 }
 
 void has_virtual_destructor() {
diff --git a/clang/test/SemaTemplate/instantiation-depth.cpp b/clang/test/SemaTemplate/instantiation-depth.cpp
index 8e1b803..c0b8bb2 100644
--- a/clang/test/SemaTemplate/instantiation-depth.cpp
+++ b/clang/test/SemaTemplate/instantiation-depth.cpp
@@ -2,12 +2,30 @@
 // RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth-5 -ftemplate-backtrace-limit=4 %s
 // RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth=5 -ftemplate-backtrace-limit=4 %s
 
+#ifndef NOEXCEPT
+
 template<typename T> struct X : X<T*> { }; \
 // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
 // expected-note 3 {{instantiation of template class}} \
 // expected-note {{skipping 2 contexts in backtrace}} \
 // expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
 
-void test() { 
+void test() {
   (void)sizeof(X<int>); // expected-note {{instantiation of template class}}
 }
+
+#else
+
+// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s
+
+template<typename T> struct S {
+  S() noexcept(noexcept(T()));
+};
+struct T : S<T> {}; \
+// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
+// expected-note 4 {{in instantiation of exception spec}} \
+// expected-note {{skipping 2 contexts in backtrace}} \
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
+T t; // expected-note {{implicit default constructor for 'T' first required here}}
+
+#endif