Instantiate exception specifications when instantiating function types (other
than the type of a function declaration). We previously didn't instantiate
these at all! This also covers the pathological case where the only mention of
a parameter pack is within the exception specification; this gives us a second
way (other than alias templates) to reach the horrible state where a type
contains an unexpanded pack, but its canonical type does not.


This is a re-commit of r219977:

r219977 was reverted in r220038 because it hit a wrong-code bug in GCC 4.7.2.
(That's gcc.gnu.org/PR56135, and affects any implicit lambda-capture of
'this' within a template.)


r219977 was a re-commit of r217995, r218011, and r218053:

r217995 was reverted in r218058 because it hit a rejects-valid bug in MSVC.
(Incorrect overload resolution in the presence of using-declarations.)
It was re-committed in r219977 with a workaround for the MSVC rejects-valid.

r218011 was a workaround for an MSVC parser bug. (Incorrect desugaring of
unbraced range-based for loop).

llvm-svn: 221750
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 07671b2..abac613 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -720,10 +720,11 @@
 /// assignment and override compatibility check. We do not check the parameters
 /// of parameter function pointers recursively, as no sane programmer would
 /// even be able to write such a function type.
-bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
-    const FunctionProtoType *Target, SourceLocation TargetLoc,
-    const FunctionProtoType *Source, SourceLocation SourceLoc)
-{
+bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &NoteID,
+                                   const FunctionProtoType *Target,
+                                   SourceLocation TargetLoc,
+                                   const FunctionProtoType *Source,
+                                   SourceLocation SourceLoc) {
   if (CheckSpecForTypesEquivalent(
           *this, PDiag(diag::err_deep_exception_specs_differ) << 0, PDiag(),
           Target->getReturnType(), TargetLoc, Source->getReturnType(),
@@ -744,23 +745,30 @@
   return false;
 }
 
-bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
-{
+bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) {
   // First we check for applicability.
   // Target type must be a function, function pointer or function reference.
   const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
-  if (!ToFunc)
+  if (!ToFunc || ToFunc->hasDependentExceptionSpec())
     return false;
 
   // SourceType must be a function or function pointer.
   const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
-  if (!FromFunc)
+  if (!FromFunc || FromFunc->hasDependentExceptionSpec())
     return false;
 
   // Now we've got the correct types on both sides, check their compatibility.
   // This means that the source of the conversion can only throw a subset of
   // the exceptions of the target, and any exception specs on arguments or
   // return types must be equivalent.
+  //
+  // FIXME: If there is a nested dependent exception specification, we should
+  // not be checking it here. This is fine:
+  //   template<typename T> void f() {
+  //     void (*p)(void (*) throw(T));
+  //     void (*q)(void (*) throw(int)) = p;
+  //   }
+  // ... because it might be instantiated with T=int.
   return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),
                                   PDiag(), ToFunc, 
                                   From->getSourceRange().getBegin(),