r218058 - Revert r217995 and follow-ups:

Hans Wennborg hans at hanshq.net
Thu Sep 18 09:01:32 PDT 2014


Author: hans
Date: Thu Sep 18 11:01:32 2014
New Revision: 218058

URL: http://llvm.org/viewvc/llvm-project?rev=218058&view=rev
Log:
Revert r217995 and follow-ups:

r218053: Use exceptions() instead of getNumExceptions()/getExceptionType() to avoid
r218011: Work around MSVC parser bug by putting redundant braces around the body of
r217997: Skip parens when detecting whether we're instantiating a function declaration.
r217995: Instantiate exception specifications when instantiating function types (other

The Windows build was broken for 16 hours and no one had any good ideas of how to
fix it. Reverting for now to make the builders green. See the cfe-commits thread [1] for
more info.

This was the build error (from [2]):

C:\bb-win7\ninja-clang-i686-msc17-R\llvm-project\clang\lib\Sema\SemaTemplateInstantiate.cpp(1590) : error C2668: '`anonymous-namespace'::TemplateInstantiator::TransformFunctionProtoType' : ambiguous call to overloaded function
        C:\bb-win7\ninja-clang-i686-msc17-R\llvm-project\clang\lib\Sema\SemaTemplateInstantiate.cpp(1313): could be 'clang::QualType `anonymous-namespace'::TemplateInstantiator::TransformFunctionProtoType<clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>>(clang::TypeLocBuilder &,clang::FunctionProtoTypeLoc,clang::CXXRecordDecl *,unsigned int,Fn)'
        with
        [
            Fn=clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>
        ]
        c:\bb-win7\ninja-clang-i686-msc17-r\llvm-project\clang\lib\sema\TreeTransform.h(4532): or       'clang::QualType clang::TreeTransform<Derived>::TransformFunctionProtoType<clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>>(clang::TypeLocBuilder &,clang::FunctionProtoTypeLoc,clang::CXXRecordDecl *,unsigned int,Fn)'
        with
        [
            Derived=`anonymous-namespace'::TemplateInstantiator,
            Fn=clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>
        ]
        while trying to match the argument list '(clang::TypeLocBuilder, clang::FunctionProtoTypeLoc, clang::CXXRecordDecl *, unsigned int, clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>)'

 1. http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20140915/115011.html
 2. http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/10515/steps/build_clang_tools_1/logs/stdio

Modified:
    cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/CXX/except/except.spec/p1.cpp
    cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
    cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp

Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Thu Sep 18 11:01:32 2014
@@ -876,9 +876,6 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
   for (const auto &E : T->exceptions()) {
     TRY_TO(TraverseType(E));
   }
-
-  if (Expr *NE = T->getNoexceptExpr())
-    TRY_TO(TraverseStmt(NE));
 })
 
 DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
@@ -1087,9 +1084,6 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType,
   for (const auto &E : T->exceptions()) {
     TRY_TO(TraverseType(E));
   }
-
-  if (Expr *NE = T->getNoexceptExpr())
-    TRY_TO(TraverseStmt(NE));
 })
 
 DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
@@ -2129,29 +2123,21 @@ bool RecursiveASTVisitor<Derived>::Trave
     TRY_TO(TraverseLambdaCapture(S, C));
   }
 
-  TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
-  FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
-
-  if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
-    // Visit the whole type.
-    TRY_TO(TraverseTypeLoc(TL));
-  } else {
-    if (S->hasExplicitParameters()) {
-      // Visit parameters.
-      for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
-        TRY_TO(TraverseDecl(Proto.getParam(I)));
+  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+      // Visit the whole type.
+      TRY_TO(TraverseTypeLoc(TL));
+    } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+      if (S->hasExplicitParameters()) {
+        // Visit parameters.
+        for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getParam(I)));
+        }
+      } else {
+        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
       }
-    } else if (S->hasExplicitResultType()) {
-      TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
     }
-
-    auto *T = Proto.getTypePtr();
-    for (const auto &E : T->exceptions()) {
-      TRY_TO(TraverseType(E));
-    }
-
-    if (Expr *NE = T->getNoexceptExpr())
-      TRY_TO(TraverseStmt(NE));
   }
 
   TRY_TO(TraverseLambdaBody(S));

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Sep 18 11:01:32 2014
@@ -2673,23 +2673,20 @@ private:
   }
 
 protected:
-  CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
-           Expr *op, unsigned BasePathSize)
-      : Expr(SC, ty, VK, OK_Ordinary,
-             // Cast expressions are type-dependent if the type is
-             // dependent (C++ [temp.dep.expr]p3).
-             ty->isDependentType(),
-             // Cast expressions are value-dependent if the type is
-             // dependent or if the subexpression is value-dependent.
-             ty->isDependentType() || (op && op->isValueDependent()),
-             (ty->isInstantiationDependentType() ||
-              (op && op->isInstantiationDependent())),
-             // An implicit cast expression doesn't (lexically) contain an
-             // unexpanded pack, even if its target type does.
-             ((SC != ImplicitCastExprClass &&
-               ty->containsUnexpandedParameterPack()) ||
-              (op && op->containsUnexpandedParameterPack()))),
-        Op(op) {
+  CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
+           const CastKind kind, Expr *op, unsigned BasePathSize) :
+    Expr(SC, ty, VK, OK_Ordinary,
+         // Cast expressions are type-dependent if the type is
+         // dependent (C++ [temp.dep.expr]p3).
+         ty->isDependentType(),
+         // Cast expressions are value-dependent if the type is
+         // dependent or if the subexpression is value-dependent.
+         ty->isDependentType() || (op && op->isValueDependent()),
+         (ty->isInstantiationDependentType() ||
+          (op && op->isInstantiationDependent())),
+         (ty->containsUnexpandedParameterPack() ||
+          (op && op->containsUnexpandedParameterPack()))),
+    Op(op) {
     assert(kind != CK_Invalid && "creating cast with invalid cast kind");
     CastExprBits.Kind = kind;
     setBasePathSize(BasePathSize);

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Sep 18 11:01:32 2014
@@ -941,9 +941,6 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
   for (const auto &E : T->exceptions()) {
     TRY_TO(TraverseType(E));
   }
-
-  if (Expr *NE = T->getNoexceptExpr())
-    TRY_TO(TraverseStmt(NE));
 })
 
 DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
@@ -1152,9 +1149,6 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType,
   for (const auto &E : T->exceptions()) {
     TRY_TO(TraverseType(E));
   }
-
-  if (Expr *NE = T->getNoexceptExpr())
-    TRY_TO(TraverseStmt(NE));
 })
 
 DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
@@ -2151,29 +2145,21 @@ bool RecursiveASTVisitor<Derived>::Trave
     TRY_TO(TraverseLambdaCapture(S, C));
   }
 
-  TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
-  FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
-
-  if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
-    // Visit the whole type.
-    TRY_TO(TraverseTypeLoc(TL));
-  } else {
-    if (S->hasExplicitParameters()) {
-      // Visit parameters.
-      for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
-        TRY_TO(TraverseDecl(Proto.getParam(I)));
+  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+      // Visit the whole type.
+      TRY_TO(TraverseTypeLoc(TL));
+    } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+      if (S->hasExplicitParameters()) {
+        // Visit parameters.
+        for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getParam(I)));
+        }
+      } else {
+        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
       }
-    } else if (S->hasExplicitResultType()) {
-      TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
     }
-
-    auto *T = Proto.getTypePtr();
-    for (const auto &E : T->exceptions()) {
-      TRY_TO(TraverseType(E));
-    }
-
-    if (Expr *NE = T->getNoexceptExpr())
-      TRY_TO(TraverseStmt(NE));
   }
 
   TRY_TO(TraverseLambdaBody(S));

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Sep 18 11:01:32 2014
@@ -3012,8 +3012,6 @@ public:
   bool hasNoexceptExceptionSpec() const {
     return isNoexceptExceptionSpec(getExceptionSpecType());
   }
-  /// \brief Return whether this function has a dependent exception spec.
-  bool hasDependentExceptionSpec() const;
   /// \brief Result type of getNoexceptSpec().
   enum NoexceptResult {
     NR_NoNoexcept,  ///< There is no noexcept specifier.
@@ -5249,8 +5247,8 @@ template <typename T> const T *Type::cas
   ArrayType_cannot_be_used_with_getAs<T> at;
   (void) at;
 
-  if (const T *ty = dyn_cast<T>(this)) return ty;
   assert(isa<T>(CanonicalType));
+  if (const T *ty = dyn_cast<T>(this)) return ty;
   return cast<T>(getUnqualifiedDesugaredType());
 }
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Sep 18 11:01:32 2014
@@ -4025,8 +4025,7 @@ public:
 
   /// \brief Check the given exception-specification and update the
   /// exception specification information with the results.
-  void checkExceptionSpecification(bool IsTopLevel,
-                                   ExceptionSpecificationType EST,
+  void checkExceptionSpecification(ExceptionSpecificationType EST,
                                    ArrayRef<ParsedType> DynamicExceptions,
                                    ArrayRef<SourceRange> DynamicExceptionRanges,
                                    Expr *NoexceptExpr,
@@ -6653,8 +6652,6 @@ public:
                                         DeclarationName Entity,
                                         CXXRecordDecl *ThisContext,
                                         unsigned ThisTypeQuals);
-  void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
-                          const MultiLevelTemplateArgumentList &Args);
   ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
                             const MultiLevelTemplateArgumentList &TemplateArgs,
                                 int indexAdjustment,

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Sep 18 11:01:32 2014
@@ -1623,9 +1623,9 @@ FunctionProtoType::FunctionProtoType(Qua
     QualType *exnSlot = argSlot + NumParams;
     unsigned I = 0;
     for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) {
-      // Note that a dependent exception specification does *not* make
-      // a type dependent; it's not even part of the C++ type system.
-      if (ExceptionType->isInstantiationDependentType())
+      if (ExceptionType->isDependentType())
+        setDependent();
+      else if (ExceptionType->isInstantiationDependentType())
         setInstantiationDependent();
 
       if (ExceptionType->containsUnexpandedParameterPack())
@@ -1639,12 +1639,11 @@ FunctionProtoType::FunctionProtoType(Qua
     *noexSlot = epi.ExceptionSpec.NoexceptExpr;
 
     if (epi.ExceptionSpec.NoexceptExpr) {
-      if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||
-          epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())
+      if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() 
+          || epi.ExceptionSpec.NoexceptExpr->isTypeDependent())
+        setDependent();
+      else if (epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())
         setInstantiationDependent();
-
-      if (epi.ExceptionSpec.NoexceptExpr->containsUnexpandedParameterPack())
-        setContainsUnexpandedParameterPack();
     }
   } else if (getExceptionSpecType() == EST_Uninstantiated) {
     // Store the function decl from which we will resolve our
@@ -1670,18 +1669,6 @@ FunctionProtoType::FunctionProtoType(Qua
   }
 }
 
-bool FunctionProtoType::hasDependentExceptionSpec() const {
-  if (Expr *NE = getNoexceptExpr())
-    return NE->isValueDependent();
-  for (QualType ET : exceptions())
-    // A pack expansion with a non-dependent pattern is still dependent,
-    // because we don't know whether the pattern is in the exception spec
-    // or not (that depends on whether the pack has 0 expansions).
-    if (ET->isDependentType() || ET->getAs<PackExpansionType>())
-      return true;
-  return false;
-}
-
 FunctionProtoType::NoexceptResult
 FunctionProtoType::getNoexceptSpec(const ASTContext &ctx) const {
   ExceptionSpecificationType est = getExceptionSpecType();

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 18 11:01:32 2014
@@ -13051,12 +13051,13 @@ bool Sema::checkThisInStaticMemberFuncti
   return false;
 }
 
-void Sema::checkExceptionSpecification(
-    bool IsTopLevel, ExceptionSpecificationType EST,
-    ArrayRef<ParsedType> DynamicExceptions,
-    ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr,
-    SmallVectorImpl<QualType> &Exceptions,
-    FunctionProtoType::ExceptionSpecInfo &ESI) {
+void
+Sema::checkExceptionSpecification(ExceptionSpecificationType EST,
+                                  ArrayRef<ParsedType> DynamicExceptions,
+                                  ArrayRef<SourceRange> DynamicExceptionRanges,
+                                  Expr *NoexceptExpr,
+                                  SmallVectorImpl<QualType> &Exceptions,
+                                  FunctionProtoType::ExceptionSpecInfo &ESI) {
   Exceptions.clear();
   ESI.Type = EST;
   if (EST == EST_Dynamic) {
@@ -13065,15 +13066,13 @@ void Sema::checkExceptionSpecification(
       // FIXME: Preserve type source info.
       QualType ET = GetTypeFromParser(DynamicExceptions[ei]);
 
-      if (IsTopLevel) {
-        SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-        collectUnexpandedParameterPacks(ET, Unexpanded);
-        if (!Unexpanded.empty()) {
-          DiagnoseUnexpandedParameterPacks(
-              DynamicExceptionRanges[ei].getBegin(), UPPC_ExceptionType,
-              Unexpanded);
-          continue;
-        }
+      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+      collectUnexpandedParameterPacks(ET, Unexpanded);
+      if (!Unexpanded.empty()) {
+        DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(),
+                                         UPPC_ExceptionType,
+                                         Unexpanded);
+        continue;
       }
 
       // Check that the type is valid for an exception spec, and
@@ -13092,8 +13091,7 @@ void Sema::checkExceptionSpecification(
               NoexceptExpr->getType()->getCanonicalTypeUnqualified() ==
               Context.BoolTy) &&
              "Parser should have made sure that the expression is boolean");
-      if (IsTopLevel && NoexceptExpr &&
-          DiagnoseUnexpandedParameterPack(NoexceptExpr)) {
+      if (NoexceptExpr && DiagnoseUnexpandedParameterPack(NoexceptExpr)) {
         ESI.Type = EST_BasicNoexcept;
         return;
       }

Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Thu Sep 18 11:01:32 2014
@@ -720,11 +720,10 @@ static bool CheckSpecForTypesEquivalent(
 /// 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(),
@@ -745,30 +744,23 @@ bool Sema::CheckParamExceptionSpec(const
   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 || ToFunc->hasDependentExceptionSpec())
+  if (!ToFunc)
     return false;
 
   // SourceType must be a function or function pointer.
   const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
-  if (!FromFunc || FromFunc->hasDependentExceptionSpec())
+  if (!FromFunc)
     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(),

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Sep 18 11:01:32 2014
@@ -788,14 +788,12 @@ namespace {
     /// pack.
     ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
 
-    // Pull in the base class overload; it just forwards to our function.
-    using inherited::TransformFunctionProtoType;
-    template<typename Fn>
+    QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
+                                        FunctionProtoTypeLoc TL);
     QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
                                         FunctionProtoTypeLoc TL,
                                         CXXRecordDecl *ThisContext,
-                                        unsigned ThisTypeQuals,
-                                        Fn TransformExceptionSpec);
+                                        unsigned ThisTypeQuals);
 
     ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
                                             int indexAdjustment,
@@ -1309,16 +1307,21 @@ ExprResult TemplateInstantiator::Transfo
                                         E->getParam());
 }
 
-template<typename Fn>
+QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
+                                                      FunctionProtoTypeLoc TL) {
+  // We need a local instantiation scope for this function prototype.
+  LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+  return inherited::TransformFunctionProtoType(TLB, TL);
+}
+
 QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                  FunctionProtoTypeLoc TL,
                                  CXXRecordDecl *ThisContext,
-                                 unsigned ThisTypeQuals,
-                                 Fn TransformExceptionSpec) {
+                                 unsigned ThisTypeQuals) {
   // We need a local instantiation scope for this function prototype.
   LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
-  return inherited::TransformFunctionProtoType(
-      TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
+  return inherited::TransformFunctionProtoType(TLB, TL, ThisContext, 
+                                               ThisTypeQuals);  
 }
 
 ParmVarDecl *
@@ -1553,8 +1556,7 @@ static bool NeedsInstantiationAsFunction
 
 /// A form of SubstType intended specifically for instantiating the
 /// type of a FunctionDecl.  Its purpose is solely to force the
-/// instantiation of default-argument expressions and to avoid
-/// instantiating an exception-specification.
+/// instantiation of default-argument expressions.
 TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
                                 const MultiLevelTemplateArgumentList &Args,
                                 SourceLocation Loc,
@@ -1577,17 +1579,9 @@ TypeSourceInfo *Sema::SubstFunctionDeclT
 
   QualType Result;
 
-  if (FunctionProtoTypeLoc Proto =
-          TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
-    // Instantiate the type, other than its exception specification. The
-    // exception specification is instantiated in InitFunctionInstantiation
-    // once we've built the FunctionDecl.
-    // FIXME: Set the exception specification to EST_Uninstantiated here,
-    // instead of rebuilding the function type again later.
-    Result = Instantiator.TransformFunctionProtoType(
-        TLB, Proto, ThisContext, ThisTypeQuals,
-        [](FunctionProtoType::ExceptionSpecInfo &ESI,
-           bool &Changed) { return false; });
+  if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+    Result = Instantiator.TransformFunctionProtoType(TLB, Proto, ThisContext,
+                                                     ThisTypeQuals);
   } else {
     Result = Instantiator.TransformType(TLB, TL);
   }
@@ -1597,26 +1591,6 @@ TypeSourceInfo *Sema::SubstFunctionDeclT
   return TLB.getTypeSourceInfo(Context, Result);
 }
 
-void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
-                              const MultiLevelTemplateArgumentList &Args) {
-  FunctionProtoType::ExceptionSpecInfo ESI =
-      Proto->getExtProtoInfo().ExceptionSpec;
-  assert(ESI.Type != EST_Uninstantiated);
-
-  TemplateInstantiator Instantiator(*this, Args, New->getLocation(),
-                                    New->getDeclName());
-
-  SmallVector<QualType, 4> ExceptionStorage;
-  bool Changed = false;
-  if (Instantiator.TransformExceptionSpec(
-          New->getTypeSourceInfo()->getTypeLoc().getLocEnd(), ESI,
-          ExceptionStorage, Changed))
-    // On error, recover by dropping the exception specification.
-    ESI.Type = EST_None;
-
-  UpdateExceptionSpec(New, ESI);
-}
-
 ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, 
                             const MultiLevelTemplateArgumentList &TemplateArgs,
                                     int indexAdjustment,

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Sep 18 11:01:32 2014
@@ -2988,7 +2988,7 @@ TemplateDeclInstantiator::SubstFunctionT
 /// Introduce the instantiated function parameters into the local
 /// instantiation scope, and set the parameter names to those used
 /// in the template.
-static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
+static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
                                              const FunctionDecl *PatternDecl,
                                              LocalInstantiationScope &Scope,
                            const MultiLevelTemplateArgumentList &TemplateArgs) {
@@ -2999,22 +2999,15 @@ static bool addInstantiatedParametersToS
       // Simple case: not a parameter pack.
       assert(FParamIdx < Function->getNumParams());
       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
-      FunctionParam->setDeclName(PatternParam->getDeclName());
       // If the parameter's type is not dependent, update it to match the type
       // in the pattern. They can differ in top-level cv-qualifiers, and we want
       // the pattern's type here. If the type is dependent, they can't differ,
-      // per core issue 1668. Substitute into the type from the pattern, in case
-      // it's instantiation-dependent.
+      // per core issue 1668.
       // FIXME: Updating the type to work around this is at best fragile.
-      if (!PatternDecl->getType()->isDependentType()) {
-        QualType T = S.SubstType(PatternParam->getType(), TemplateArgs,
-                                 FunctionParam->getLocation(),
-                                 FunctionParam->getDeclName());
-        if (T.isNull())
-          return true;
-        FunctionParam->setType(T);
-      }
+      if (!PatternDecl->getType()->isDependentType())
+        FunctionParam->setType(PatternParam->getType());
 
+      FunctionParam->setDeclName(PatternParam->getDeclName());
       Scope.InstantiatedLocal(PatternParam, FunctionParam);
       ++FParamIdx;
       continue;
@@ -3026,27 +3019,136 @@ static bool addInstantiatedParametersToS
       = S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs);
     assert(NumArgumentsInExpansion &&
            "should only be called when all template arguments are known");
-    QualType PatternType =
-        PatternParam->getType()->castAs<PackExpansionType>()->getPattern();
     for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+      if (!PatternDecl->getType()->isDependentType())
+        FunctionParam->setType(PatternParam->getType());
+
       FunctionParam->setDeclName(PatternParam->getDeclName());
-      if (!PatternDecl->getType()->isDependentType()) {
-        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, Arg);
-        QualType T = S.SubstType(PatternType, TemplateArgs,
-                                 FunctionParam->getLocation(),
-                                 FunctionParam->getDeclName());
+      Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
+      ++FParamIdx;
+    }
+  }
+}
+
+static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New,
+                                     const FunctionProtoType *Proto,
+                           const MultiLevelTemplateArgumentList &TemplateArgs) {
+  assert(Proto->getExceptionSpecType() != EST_Uninstantiated);
+
+  // C++11 [expr.prim.general]p3:
+  //   If a declaration declares a member function or member function 
+  //   template of a class X, the expression this is a prvalue of type 
+  //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
+  //   and the end of the function-definition, member-declarator, or 
+  //   declarator.    
+  CXXRecordDecl *ThisContext = nullptr;
+  unsigned ThisTypeQuals = 0;
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(New)) {
+    ThisContext = Method->getParent();
+    ThisTypeQuals = Method->getTypeQualifiers();
+  }
+  Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals,
+                                   SemaRef.getLangOpts().CPlusPlus11);
+
+  // The function has an exception specification or a "noreturn"
+  // attribute. Substitute into each of the exception types.
+  SmallVector<QualType, 4> Exceptions;
+  for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) {
+    // FIXME: Poor location information!
+    if (const PackExpansionType *PackExpansion
+          = Proto->getExceptionType(I)->getAs<PackExpansionType>()) {
+      // We have a pack expansion. Instantiate it.
+      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+      SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
+                                              Unexpanded);
+      assert(!Unexpanded.empty() &&
+             "Pack expansion without parameter packs?");
+
+      bool Expand = false;
+      bool RetainExpansion = false;
+      Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
+      if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),
+                                                  SourceRange(),
+                                                  Unexpanded,
+                                                  TemplateArgs,
+                                                  Expand,
+                                                  RetainExpansion,
+                                                  NumExpansions))
+        break;
+
+      if (!Expand) {
+        // We can't expand this pack expansion into separate arguments yet;
+        // just substitute into the pattern and create a new pack expansion
+        // type.
+        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
+        QualType T = SemaRef.SubstType(PackExpansion->getPattern(),
+                                       TemplateArgs,
+                                     New->getLocation(), New->getDeclName());
         if (T.isNull())
-          return true;
-        FunctionParam->setType(T);
+          break;
+
+        T = SemaRef.Context.getPackExpansionType(T, NumExpansions);
+        Exceptions.push_back(T);
+        continue;
       }
 
-      Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
-      ++FParamIdx;
+      // Substitute into the pack expansion pattern for each template
+      bool Invalid = false;
+      for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
+        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx);
+
+        QualType T = SemaRef.SubstType(PackExpansion->getPattern(),
+                                       TemplateArgs,
+                                     New->getLocation(), New->getDeclName());
+        if (T.isNull()) {
+          Invalid = true;
+          break;
+        }
+
+        Exceptions.push_back(T);
+      }
+
+      if (Invalid)
+        break;
+
+      continue;
+    }
+
+    QualType T
+      = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs,
+                          New->getLocation(), New->getDeclName());
+    if (T.isNull() ||
+        SemaRef.CheckSpecifiedExceptionType(T, New->getLocation()))
+      continue;
+
+    Exceptions.push_back(T);
+  }
+  Expr *NoexceptExpr = nullptr;
+  if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) {
+    EnterExpressionEvaluationContext Unevaluated(SemaRef,
+                                                 Sema::ConstantEvaluated);
+    ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs);
+    if (E.isUsable())
+      E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart());
+
+    if (E.isUsable()) {
+      NoexceptExpr = E.get();
+      if (!NoexceptExpr->isTypeDependent() &&
+          !NoexceptExpr->isValueDependent())
+        NoexceptExpr
+          = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
+              nullptr, diag::err_noexcept_needs_constant_expression,
+              /*AllowFold*/ false).get();
     }
   }
 
-  return false;
+  FunctionProtoType::ExceptionSpecInfo ESI;
+  ESI.Type = Proto->getExceptionSpecType();
+  ESI.Exceptions = Exceptions;
+  ESI.NoexceptExpr = NoexceptExpr;
+
+  SemaRef.UpdateExceptionSpec(New, ESI);
 }
 
 void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
@@ -3073,14 +3175,11 @@ void Sema::InstantiateExceptionSpec(Sour
     getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true);
 
   FunctionDecl *Template = Proto->getExceptionSpecTemplate();
-  if (addInstantiatedParametersToScope(*this, Decl, Template, Scope,
-                                       TemplateArgs)) {
-    UpdateExceptionSpec(Decl, EST_None);
-    return;
-  }
+  addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs);
 
-  SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(),
-                     TemplateArgs);
+  ::InstantiateExceptionSpec(*this, Decl,
+                             Template->getType()->castAs<FunctionProtoType>(),
+                             TemplateArgs);
 }
 
 /// \brief Initializes the common fields of an instantiation function
@@ -3149,7 +3248,7 @@ TemplateDeclInstantiator::InitFunctionIn
       New->setType(SemaRef.Context.getFunctionType(
           NewProto->getReturnType(), NewProto->getParamTypes(), EPI));
     } else {
-      SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);
+      ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs);
     }
   }
 
@@ -3339,9 +3438,8 @@ void Sema::InstantiateFunctionDefinition
     MultiLevelTemplateArgumentList TemplateArgs =
       getTemplateInstantiationArgs(Function, nullptr, false, PatternDecl);
 
-    if (addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope,
-                                         TemplateArgs))
-      return;
+    addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope,
+                                     TemplateArgs);
 
     // If this is a constructor, instantiate the member initializers.
     if (const CXXConstructorDecl *Ctor =

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Sep 18 11:01:32 2014
@@ -2989,8 +2989,7 @@ static TypeSourceInfo *GetFullTypeForDec
           NoexceptExpr = FTI.NoexceptExpr;
         }
 
-        S.checkExceptionSpecification(D.isFunctionDeclarationContext(),
-                                      FTI.getExceptionSpecType(),
+        S.checkExceptionSpecification(FTI.getExceptionSpecType(),
                                       DynamicExceptions,
                                       DynamicExceptionRanges,
                                       NoexceptExpr,

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Sep 18 11:01:32 2014
@@ -542,17 +542,10 @@ public:
   QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
 #include "clang/AST/TypeLocNodes.def"
 
-  template<typename Fn>
   QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
                                       FunctionProtoTypeLoc TL,
                                       CXXRecordDecl *ThisContext,
-                                      unsigned ThisTypeQuals,
-                                      Fn TransformExceptionSpec);
-
-  bool TransformExceptionSpec(SourceLocation Loc,
-                              FunctionProtoType::ExceptionSpecInfo &ESI,
-                              SmallVectorImpl<QualType> &Exceptions,
-                              bool &Changed);
+                                      unsigned ThisTypeQuals);
 
   StmtResult TransformSEHHandler(Stmt *Handler);
 
@@ -4519,19 +4512,15 @@ template<typename Derived>
 QualType
 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                                    FunctionProtoTypeLoc TL) {
-  SmallVector<QualType, 4> ExceptionStorage;
-  return getDerived().TransformFunctionProtoType(
-      TLB, TL, nullptr, 0,
-      [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
-        return TransformExceptionSpec(TL.getBeginLoc(), ESI, ExceptionStorage,
-                                      Changed);
-      });
+  return getDerived().TransformFunctionProtoType(TLB, TL, nullptr, 0);
 }
 
-template<typename Derived> template<typename Fn>
-QualType TreeTransform<Derived>::TransformFunctionProtoType(
-    TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
-    unsigned ThisTypeQuals, Fn TransformExceptionSpec) {
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
+                                                   FunctionProtoTypeLoc TL,
+                                                   CXXRecordDecl *ThisContext,
+                                                   unsigned ThisTypeQuals) {
   // Transform the parameters and return type.
   //
   // We are required to instantiate the params and return type in source order.
@@ -4576,21 +4565,15 @@ QualType TreeTransform<Derived>::Transfo
       return QualType();
   }
 
-  FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
-
-  bool EPIChanged = false;
-  if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
-    return QualType();
-
-  // FIXME: Need to transform ConsumedParameters for variadic template
-  // expansion.
+  // FIXME: Need to transform the exception-specification too.
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
       T->getNumParams() != ParamTypes.size() ||
       !std::equal(T->param_type_begin(), T->param_type_end(),
-                  ParamTypes.begin()) || EPIChanged) {
-    Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
+                  ParamTypes.begin())) {
+    Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes,
+                                                   T->getExtProtoInfo());
     if (Result.isNull())
       return QualType();
   }
@@ -4607,107 +4590,6 @@ QualType TreeTransform<Derived>::Transfo
 }
 
 template<typename Derived>
-bool TreeTransform<Derived>::TransformExceptionSpec(
-    SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
-    SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
-  assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
-
-  // Instantiate a dynamic noexcept expression, if any.
-  if (ESI.Type == EST_ComputedNoexcept) {
-    EnterExpressionEvaluationContext Unevaluated(getSema(),
-                                                 Sema::ConstantEvaluated);
-    ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
-    if (NoexceptExpr.isInvalid())
-      return true;
-
-    NoexceptExpr = getSema().CheckBooleanCondition(
-        NoexceptExpr.get(), NoexceptExpr.get()->getLocStart());
-    if (NoexceptExpr.isInvalid())
-      return true;
-
-    if (!NoexceptExpr.get()->isValueDependent()) {
-      NoexceptExpr = getSema().VerifyIntegerConstantExpression(
-          NoexceptExpr.get(), nullptr,
-          diag::err_noexcept_needs_constant_expression,
-          /*AllowFold*/false);
-      if (NoexceptExpr.isInvalid())
-        return true;
-    }
-
-    if (ESI.NoexceptExpr != NoexceptExpr.get())
-      Changed = true;
-    ESI.NoexceptExpr = NoexceptExpr.get();
-  }
-
-  if (ESI.Type != EST_Dynamic)
-    return false;
-
-  // Instantiate a dynamic exception specification's type.
-  for (QualType T : ESI.Exceptions) {
-    if (const PackExpansionType *PackExpansion =
-            T->getAs<PackExpansionType>()) {
-      Changed = true;
-
-      // We have a pack expansion. Instantiate it.
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
-                                              Unexpanded);
-      assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
-
-      // Determine whether the set of unexpanded parameter packs can and
-      // should
-      // be expanded.
-      bool Expand = false;
-      bool RetainExpansion = false;
-      Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
-      // FIXME: Track the location of the ellipsis (and track source location
-      // information for the types in the exception specification in general).
-      if (getDerived().TryExpandParameterPacks(
-              Loc, SourceRange(), Unexpanded, Expand,
-              RetainExpansion, NumExpansions))
-        return true;
-
-      if (!Expand) {
-        // We can't expand this pack expansion into separate arguments yet;
-        // just substitute into the pattern and create a new pack expansion
-        // type.
-        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
-        QualType U = getDerived().TransformType(PackExpansion->getPattern());
-        if (U.isNull())
-          return true;
-
-        U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
-        Exceptions.push_back(U);
-        continue;
-      }
-
-      // Substitute into the pack expansion pattern for each slice of the
-      // pack.
-      for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
-        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
-
-        QualType U = getDerived().TransformType(PackExpansion->getPattern());
-        if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
-          return true;
-
-        Exceptions.push_back(U);
-      }
-    } else {
-      QualType U = getDerived().TransformType(T);
-      if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
-        return true;
-      if (T != U)
-        Changed = true;
-
-      Exceptions.push_back(U);
-    }
-  }
-
-  ESI.Exceptions = Exceptions;
-  return false;
-}
-
-template<typename Derived>
 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
                                                  TypeLocBuilder &TLB,
                                                  FunctionNoProtoTypeLoc TL) {
@@ -9024,13 +8906,9 @@ TreeTransform<Derived>::TransformLambdaE
     // transformed parameters.
 
     TypeLocBuilder NewCallOpTLBuilder;
-    SmallVector<QualType, 4> ExceptionStorage;
-    QualType NewCallOpType = TransformFunctionProtoType(
-        NewCallOpTLBuilder, OldCallOpFPTL, nullptr, 0,
-        [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
-          return TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
-                                        ExceptionStorage, Changed);
-        });
+    QualType NewCallOpType = TransformFunctionProtoType(NewCallOpTLBuilder, 
+                                                        OldCallOpFPTL, 
+                                                        nullptr, 0);
     NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
                                                         NewCallOpType);
   }

Modified: cfe/trunk/test/CXX/except/except.spec/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p1.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/test/CXX/except/except.spec/p1.cpp (original)
+++ cfe/trunk/test/CXX/except/except.spec/p1.cpp Thu Sep 18 11:01:32 2014
@@ -77,12 +77,5 @@ namespace PR11084 {
     static int f() noexcept(1/X) { return 10; }  // expected-error{{argument to noexcept specifier must be a constant expression}} expected-note{{division by zero}}
   };
 
-  template<int X> void f() {
-    int (*p)() noexcept(1/X); // expected-error{{argument to noexcept specifier must be a constant expression}} expected-note{{division by zero}}
-  };
-
-  void g() {
-    A<0>::f(); // expected-note{{in instantiation of exception specification for 'f'}}
-    f<0>(); // expected-note{{in instantiation of function template specialization}}
-  }
+  void g() { A<0>::f(); } // expected-note{{in instantiation of exception specification for 'f' requested here}}
 }

Modified: cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp Thu Sep 18 11:01:32 2014
@@ -58,13 +58,6 @@ namespace dr1330_example {
     S().f<S>(); // ok
     S().f<int>(); // expected-note {{instantiation of exception spec}}
   }
-
-  template<typename T>
-  struct U {
-    void f() noexcept(T::error);
-    void (g)() noexcept(T::error);
-  };
-  U<int> uint; // ok
 }
 
 namespace core_19754_example {
@@ -144,37 +137,3 @@ namespace PR12763 {
   };
   void X::g() {} // expected-note {{in instantiation of}}
 }
-
-namespace Variadic {
-  template<bool B> void check() { static_assert(B, ""); }
-  template<bool B, bool B2, bool ...Bs> void check() { static_assert(B, ""); check<B2, Bs...>(); }
-
-  template<typename ...T> void consume(T...);
-
-  template<typename ...T> void f(void (*...p)() throw (T)) {
-    void (*q[])() = { p... };
-    consume((p(),0)...);
-  }
-  template<bool ...B> void g(void (*...p)() noexcept (B)) {
-    consume((p(),0)...);
-    check<noexcept(p()) == B ...>();
-  }
-  template<typename ...T> void i() {
-    consume([]() throw(T) {} ...);
-    consume([]() noexcept(sizeof(T) == 4) {} ...);
-  }
-  template<bool ...B> void j() {
-    consume([](void (*p)() noexcept(B)) {
-      void (*q)() noexcept = p; // expected-error {{not superset of source}}
-    } ...);
-  }
-
-  void z() {
-    f<int, char, double>(nullptr, nullptr, nullptr);
-    g<true, false, true>(nullptr, nullptr, nullptr);
-    i<int, long, short>();
-    j<true, true>();
-    j<true, false>(); // expected-note {{in instantiation of}}
-  }
-
-}

Modified: cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp?rev=218058&r1=218057&r2=218058&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp Thu Sep 18 11:01:32 2014
@@ -1,7 +1,5 @@
-// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -verify %s -DERRORS
-// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -emit-llvm-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
-#ifdef ERRORS
 template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
 struct Incomplete; // expected-note{{forward}}
 
@@ -9,20 +7,3 @@ void test_f1(Incomplete *incomplete_p, i
   f1(int_p);
   f1(incomplete_p); // expected-note{{instantiation of}}
 }
-#endif
-
-template<typename T> void f(void (*p)() throw(T)) {
-#ifdef ERRORS
-  void (*q)() throw(char) = p; // expected-error {{target exception spec}}
-
-  extern void (*p2)() throw(T);
-  void (*q2)() throw(char) = p2; // expected-error {{target exception spec}}
-
-  extern void (*p3)() throw(char);
-  void (*q3)() throw(T) = p3; // expected-error {{target exception spec}}
-
-  void (*q4)() throw(T) = p2; // ok
-#endif
-  p();
-}
-void g() { f<int>(0); } // expected-note {{instantiation of}}





More information about the cfe-commits mailing list