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).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160847 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 595d428..61c4c33 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/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}}
+}