r217995 - Instantiate exception specifications when instantiating function types (other
Yaron Keren
yaron.keren at gmail.com
Thu Sep 18 05:23:44 PDT 2014
Didn't work here either, MSVC 2013 update 2, same error as Timur.
2014-09-18 12:56 GMT+03:00 Timur Iskhodzhanov <timurrrr at google.com>:
> I don't think it worked:
> ..\tools\clang\lib\Sema\SemaTemplateInstantiate.cpp(1590) : error C2668:
> 'clang::TreeTransform<`anonymous-namespace'::TemplateInstantiator>::TransformFunctionProtoType'
> :
> ambiguous call to overloaded function
> ..\tools\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>
> ]
> d:\src\llvm-trunk\tools\clang\lib\sema\TreeTransform.h(4532): or
> 'clang::QualType
> clang::TreeTransform<`anonymous-namespace'::TemplateInstantiator>::Transfo
> rmFunctionProtoType<clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>>(clang::TypeLocBuilder
> &,clang::FunctionProtoTypeLoc,clang::CXXRecordDec
> l *,unsigned int,Fn)'
> with
> [
>
> Fn=clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>
> ]
> while trying to match the argument list '(clang::TypeLocBuilder,
> clang::FunctionProtoTypeLoc, clang::CXXRecordDecl *, unsigned int,
> clang::Sema::SubstFunctionDecl
> Type::<lambda_756edcbe7bd5c7584849a6e3a1491735>)'
>
> 2014-09-18 7:59 GMT+04:00 Richard Smith <richard at metafoo.co.uk>:
>
>> Thanks, should be fixed in r218011.
>>
>> On Wed, Sep 17, 2014 at 8:19 PM, Bataev, Alexey <a.bataev at hotmail.com>
>> wrote:
>>
>>> + for (const auto &E : T->exceptions())
>>> + TRY_TO(TraverseType(E));
>>>
>>> You just need to enclose the body of this loop into braces.
>>>
>>> Best regards,
>>> Alexey Bataev
>>> =============
>>> Software Engineer
>>> Intel Compiler Team
>>> Intel Corp.
>>>
>>> 18.09.2014 7:10, Reid Kleckner пишет:
>>>
>>> This appears to not compile with MSVC 2013:
>>> llvm\tools\clang\include\clang/AST/RecursiveASTVisitor.h(2171) : error
>>> C2059: syntax error : '}'
>>>
>>> http://build.chromium.org/p/chromium.fyi/builders/Cr%20Win%20Clang/builds/395/steps/runhooks/logs/stdio
>>>
>>> I believe it is trying to say that TRY_TO doesn't work inside of
>>> range-based for loops due to some insanity. This is a known issue when
>>> updating RAV. =/
>>>
>>> On Wed, Sep 17, 2014 at 4:57 PM, Richard Smith <
>>> richard-llvm at metafoo.co.uk> wrote:
>>>
>>>> Author: rsmith
>>>> Date: Wed Sep 17 18:57:05 2014
>>>> New Revision: 217995
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=217995&view=rev
>>>> Log:
>>>> 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.
>>>>
>>>> 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
>>>> +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Wed Sep 17
>>>> 18:57:05 2014
>>>> @@ -876,6 +876,9 @@ 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, {})
>>>> @@ -1084,6 +1087,9 @@ 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, {})
>>>> @@ -2123,21 +2129,28 @@ bool RecursiveASTVisitor<Derived>::Trave
>>>> TRY_TO(TraverseLambdaCapture(S, C));
>>>> }
>>>>
>>>> - 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()));
>>>> + 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)));
>>>> }
>>>> + } 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/AST/Expr.h (original)
>>>> +++ cfe/trunk/include/clang/AST/Expr.h Wed Sep 17 18:57:05 2014
>>>> @@ -2673,20 +2673,23 @@ 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())),
>>>> - (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())),
>>>> + // 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) {
>>>> 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
>>>> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Sep 17
>>>> 18:57:05 2014
>>>> @@ -941,6 +941,9 @@ 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, {})
>>>> @@ -1149,6 +1152,9 @@ 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, {})
>>>> @@ -2145,21 +2151,28 @@ bool RecursiveASTVisitor<Derived>::Trave
>>>> TRY_TO(TraverseLambdaCapture(S, C));
>>>> }
>>>>
>>>> - 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()));
>>>> + 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)));
>>>> }
>>>> + } 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/AST/Type.h (original)
>>>> +++ cfe/trunk/include/clang/AST/Type.h Wed Sep 17 18:57:05 2014
>>>> @@ -3012,6 +3012,8 @@ 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.
>>>> @@ -5247,8 +5249,8 @@ template <typename T> const T *Type::cas
>>>> ArrayType_cannot_be_used_with_getAs<T> at;
>>>> (void) at;
>>>>
>>>> - assert(isa<T>(CanonicalType));
>>>> if (const T *ty = dyn_cast<T>(this)) return ty;
>>>> + assert(isa<T>(CanonicalType));
>>>> 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>>> +++ cfe/trunk/include/clang/Sema/Sema.h Wed Sep 17 18:57:05 2014
>>>> @@ -4025,7 +4025,8 @@ public:
>>>>
>>>> /// \brief Check the given exception-specification and update the
>>>> /// exception specification information with the results.
>>>> - void checkExceptionSpecification(ExceptionSpecificationType EST,
>>>> + void checkExceptionSpecification(bool IsTopLevel,
>>>> + ExceptionSpecificationType EST,
>>>> ArrayRef<ParsedType>
>>>> DynamicExceptions,
>>>> ArrayRef<SourceRange>
>>>> DynamicExceptionRanges,
>>>> Expr *NoexceptExpr,
>>>> @@ -6652,6 +6653,8 @@ 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/AST/Type.cpp (original)
>>>> +++ cfe/trunk/lib/AST/Type.cpp Wed Sep 17 18:57:05 2014
>>>> @@ -1623,9 +1623,9 @@ FunctionProtoType::FunctionProtoType(Qua
>>>> QualType *exnSlot = argSlot + NumParams;
>>>> unsigned I = 0;
>>>> for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) {
>>>> - if (ExceptionType->isDependentType())
>>>> - setDependent();
>>>> - else if (ExceptionType->isInstantiationDependentType())
>>>> + // 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())
>>>> setInstantiationDependent();
>>>>
>>>> if (ExceptionType->containsUnexpandedParameterPack())
>>>> @@ -1639,11 +1639,12 @@ FunctionProtoType::FunctionProtoType(Qua
>>>> *noexSlot = epi.ExceptionSpec.NoexceptExpr;
>>>>
>>>> if (epi.ExceptionSpec.NoexceptExpr) {
>>>> - if (epi.ExceptionSpec.NoexceptExpr->isValueDependent()
>>>> - || epi.ExceptionSpec.NoexceptExpr->isTypeDependent())
>>>> - setDependent();
>>>> - else if
>>>> (epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())
>>>> + if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||
>>>> + 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
>>>> @@ -1669,6 +1670,19 @@ FunctionProtoType::FunctionProtoType(Qua
>>>> }
>>>> }
>>>>
>>>> +bool FunctionProtoType::hasDependentExceptionSpec() const {
>>>> + if (Expr *NE = getNoexceptExpr())
>>>> + return NE->isValueDependent();
>>>> + for (unsigned I = 0, N = getNumExceptions(); I != N; ++I)
>>>> + // 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 (getExceptionType(I)->isDependentType() ||
>>>> + getExceptionType(I)->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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep 17 18:57:05 2014
>>>> @@ -13051,13 +13051,12 @@ bool Sema::checkThisInStaticMemberFuncti
>>>> return false;
>>>> }
>>>>
>>>> -void
>>>> -Sema::checkExceptionSpecification(ExceptionSpecificationType EST,
>>>> - ArrayRef<ParsedType>
>>>> DynamicExceptions,
>>>> - ArrayRef<SourceRange>
>>>> DynamicExceptionRanges,
>>>> - Expr *NoexceptExpr,
>>>> - SmallVectorImpl<QualType>
>>>> &Exceptions,
>>>> - FunctionProtoType::ExceptionSpecInfo
>>>> &ESI) {
>>>> +void Sema::checkExceptionSpecification(
>>>> + bool IsTopLevel, 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) {
>>>> @@ -13066,13 +13065,15 @@ Sema::checkExceptionSpecification(Except
>>>> // FIXME: Preserve type source info.
>>>> QualType ET = GetTypeFromParser(DynamicExceptions[ei]);
>>>>
>>>> - SmallVector<UnexpandedParameterPack, 2> Unexpanded;
>>>> - collectUnexpandedParameterPacks(ET, Unexpanded);
>>>> - if (!Unexpanded.empty()) {
>>>> -
>>>> DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(),
>>>> - UPPC_ExceptionType,
>>>> - Unexpanded);
>>>> - continue;
>>>> + if (IsTopLevel) {
>>>> + 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
>>>> @@ -13091,7 +13092,8 @@ Sema::checkExceptionSpecification(Except
>>>> NoexceptExpr->getType()->getCanonicalTypeUnqualified() ==
>>>> Context.BoolTy) &&
>>>> "Parser should have made sure that the expression is
>>>> boolean");
>>>> - if (NoexceptExpr &&
>>>> DiagnoseUnexpandedParameterPack(NoexceptExpr)) {
>>>> + if (IsTopLevel && 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Wed Sep 17 18:57:05 2014
>>>> @@ -720,10 +720,11 @@ 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(),
>>>> @@ -744,23 +745,30 @@ 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)
>>>> + 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(),
>>>>
>>>> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Sep 17 18:57:05
>>>> 2014
>>>> @@ -788,12 +788,14 @@ namespace {
>>>> /// pack.
>>>> ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
>>>>
>>>> - QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
>>>> - FunctionProtoTypeLoc TL);
>>>> + // Pull in the base class overload; it just forwards to our
>>>> function.
>>>> + using inherited::TransformFunctionProtoType;
>>>> + template<typename Fn>
>>>> QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
>>>> FunctionProtoTypeLoc TL,
>>>> CXXRecordDecl *ThisContext,
>>>> - unsigned ThisTypeQuals);
>>>> + unsigned ThisTypeQuals,
>>>> + Fn TransformExceptionSpec);
>>>>
>>>> ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
>>>> int indexAdjustment,
>>>> @@ -1307,21 +1309,16 @@ ExprResult TemplateInstantiator::Transfo
>>>> E->getParam());
>>>> }
>>>>
>>>> -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);
>>>> -}
>>>> -
>>>> +template<typename Fn>
>>>> QualType
>>>> TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
>>>> FunctionProtoTypeLoc TL,
>>>> CXXRecordDecl *ThisContext,
>>>> - unsigned ThisTypeQuals) {
>>>> + unsigned ThisTypeQuals,
>>>> + Fn TransformExceptionSpec) {
>>>> // We need a local instantiation scope for this function prototype.
>>>> LocalInstantiationScope Scope(SemaRef,
>>>> /*CombineWithOuterScope=*/true);
>>>> - return inherited::TransformFunctionProtoType(TLB, TL, ThisContext,
>>>> - ThisTypeQuals);
>>>> + return inherited::TransformFunctionProtoType(
>>>> + TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
>>>> }
>>>>
>>>> ParmVarDecl *
>>>> @@ -1556,7 +1553,8 @@ 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.
>>>> +/// instantiation of default-argument expressions and to avoid
>>>> +/// instantiating an exception-specification.
>>>> TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
>>>> const MultiLevelTemplateArgumentList
>>>> &Args,
>>>> SourceLocation Loc,
>>>> @@ -1579,9 +1577,17 @@ TypeSourceInfo *Sema::SubstFunctionDeclT
>>>>
>>>> QualType Result;
>>>>
>>>> + // FIXME: What if the function type is parenthesized?
>>>> if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
>>>> - Result = Instantiator.TransformFunctionProtoType(TLB, Proto,
>>>> ThisContext,
>>>> - ThisTypeQuals);
>>>> + // 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; });
>>>> } else {
>>>> Result = Instantiator.TransformType(TLB, TL);
>>>> }
>>>> @@ -1591,6 +1597,26 @@ 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Sep 17
>>>> 18:57:05 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 void addInstantiatedParametersToScope(Sema &S, FunctionDecl
>>>> *Function,
>>>> +static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl
>>>> *Function,
>>>> const FunctionDecl
>>>> *PatternDecl,
>>>> LocalInstantiationScope
>>>> &Scope,
>>>> const MultiLevelTemplateArgumentList
>>>> &TemplateArgs) {
>>>> @@ -2999,15 +2999,22 @@ static void 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.
>>>> + // per core issue 1668. Substitute into the type from the
>>>> pattern, in case
>>>> + // it's instantiation-dependent.
>>>> // FIXME: Updating the type to work around this is at best
>>>> fragile.
>>>> - if (!PatternDecl->getType()->isDependentType())
>>>> - FunctionParam->setType(PatternParam->getType());
>>>> + if (!PatternDecl->getType()->isDependentType()) {
>>>> + QualType T = S.SubstType(PatternParam->getType(), TemplateArgs,
>>>> + FunctionParam->getLocation(),
>>>> + FunctionParam->getDeclName());
>>>> + if (T.isNull())
>>>> + return true;
>>>> + FunctionParam->setType(T);
>>>> + }
>>>>
>>>> - FunctionParam->setDeclName(PatternParam->getDeclName());
>>>> Scope.InstantiatedLocal(PatternParam, FunctionParam);
>>>> ++FParamIdx;
>>>> continue;
>>>> @@ -3019,136 +3026,27 @@ static void 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());
>>>> - 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 (!PatternDecl->getType()->isDependentType()) {
>>>> + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, Arg);
>>>> + QualType T = S.SubstType(PatternType, TemplateArgs,
>>>> + FunctionParam->getLocation(),
>>>> + FunctionParam->getDeclName());
>>>> if (T.isNull())
>>>> - break;
>>>> -
>>>> - T = SemaRef.Context.getPackExpansionType(T, NumExpansions);
>>>> - Exceptions.push_back(T);
>>>> - continue;
>>>> - }
>>>> -
>>>> - // 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);
>>>> + return true;
>>>> + FunctionParam->setType(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();
>>>> + Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
>>>> + ++FParamIdx;
>>>> }
>>>> }
>>>>
>>>> - FunctionProtoType::ExceptionSpecInfo ESI;
>>>> - ESI.Type = Proto->getExceptionSpecType();
>>>> - ESI.Exceptions = Exceptions;
>>>> - ESI.NoexceptExpr = NoexceptExpr;
>>>> -
>>>> - SemaRef.UpdateExceptionSpec(New, ESI);
>>>> + return false;
>>>> }
>>>>
>>>> void Sema::InstantiateExceptionSpec(SourceLocation
>>>> PointOfInstantiation,
>>>> @@ -3175,11 +3073,14 @@ void Sema::InstantiateExceptionSpec(Sour
>>>> getTemplateInstantiationArgs(Decl, nullptr,
>>>> /*RelativeToPrimary*/true);
>>>>
>>>> FunctionDecl *Template = Proto->getExceptionSpecTemplate();
>>>> - addInstantiatedParametersToScope(*this, Decl, Template, Scope,
>>>> TemplateArgs);
>>>> + if (addInstantiatedParametersToScope(*this, Decl, Template, Scope,
>>>> + TemplateArgs)) {
>>>> + UpdateExceptionSpec(Decl, EST_None);
>>>> + return;
>>>> + }
>>>>
>>>> - ::InstantiateExceptionSpec(*this, Decl,
>>>> -
>>>> Template->getType()->castAs<FunctionProtoType>(),
>>>> - TemplateArgs);
>>>> + SubstExceptionSpec(Decl,
>>>> Template->getType()->castAs<FunctionProtoType>(),
>>>> + TemplateArgs);
>>>> }
>>>>
>>>> /// \brief Initializes the common fields of an instantiation function
>>>> @@ -3248,7 +3149,7 @@ TemplateDeclInstantiator::InitFunctionIn
>>>> New->setType(SemaRef.Context.getFunctionType(
>>>> NewProto->getReturnType(), NewProto->getParamTypes(), EPI));
>>>> } else {
>>>> - ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs);
>>>> + SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);
>>>> }
>>>> }
>>>>
>>>> @@ -3438,8 +3339,9 @@ void Sema::InstantiateFunctionDefinition
>>>> MultiLevelTemplateArgumentList TemplateArgs =
>>>> getTemplateInstantiationArgs(Function, nullptr, false,
>>>> PatternDecl);
>>>>
>>>> - addInstantiatedParametersToScope(*this, Function, PatternDecl,
>>>> Scope,
>>>> - TemplateArgs);
>>>> + if (addInstantiatedParametersToScope(*this, Function, PatternDecl,
>>>> Scope,
>>>> + TemplateArgs))
>>>> + return;
>>>>
>>>> // 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Sep 17 18:57:05 2014
>>>> @@ -2989,7 +2989,8 @@ static TypeSourceInfo *GetFullTypeForDec
>>>> NoexceptExpr = FTI.NoexceptExpr;
>>>> }
>>>>
>>>> - S.checkExceptionSpecification(FTI.getExceptionSpecType(),
>>>> + S.checkExceptionSpecification(D.isFunctionDeclarationContext(),
>>>> + 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>>>> +++ cfe/trunk/lib/Sema/TreeTransform.h Wed Sep 17 18:57:05 2014
>>>> @@ -542,10 +542,17 @@ 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);
>>>> + unsigned ThisTypeQuals,
>>>> + Fn TransformExceptionSpec);
>>>> +
>>>> + bool TransformExceptionSpec(SourceLocation Loc,
>>>> + FunctionProtoType::ExceptionSpecInfo
>>>> &ESI,
>>>> + SmallVectorImpl<QualType> &Exceptions,
>>>> + bool &Changed);
>>>>
>>>> StmtResult TransformSEHHandler(Stmt *Handler);
>>>>
>>>> @@ -4512,15 +4519,19 @@ template<typename Derived>
>>>> QualType
>>>> TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
>>>>
>>>> FunctionProtoTypeLoc TL) {
>>>> - return getDerived().TransformFunctionProtoType(TLB, TL, nullptr, 0);
>>>> + SmallVector<QualType, 4> ExceptionStorage;
>>>> + return getDerived().TransformFunctionProtoType(
>>>> + TLB, TL, nullptr, 0,
>>>> + [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
>>>> + return TransformExceptionSpec(TL.getBeginLoc(), ESI,
>>>> ExceptionStorage,
>>>> + Changed);
>>>> + });
>>>> }
>>>>
>>>> -template<typename Derived>
>>>> -QualType
>>>> -TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
>>>> -
>>>> FunctionProtoTypeLoc TL,
>>>> - CXXRecordDecl
>>>> *ThisContext,
>>>> - unsigned
>>>> ThisTypeQuals) {
>>>> +template<typename Derived> template<typename Fn>
>>>> +QualType TreeTransform<Derived>::TransformFunctionProtoType(
>>>> + TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl
>>>> *ThisContext,
>>>> + unsigned ThisTypeQuals, Fn TransformExceptionSpec) {
>>>> // Transform the parameters and return type.
>>>> //
>>>> // We are required to instantiate the params and return type in
>>>> source order.
>>>> @@ -4565,15 +4576,21 @@ TreeTransform<Derived>::TransformFunctio
>>>> return QualType();
>>>> }
>>>>
>>>> - // FIXME: Need to transform the exception-specification too.
>>>> + FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
>>>> +
>>>> + bool EPIChanged = false;
>>>> + if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
>>>> + return QualType();
>>>> +
>>>> + // FIXME: Need to transform ConsumedParameters for variadic template
>>>> + // expansion.
>>>>
>>>> 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())) {
>>>> - Result = getDerived().RebuildFunctionProtoType(ResultType,
>>>> ParamTypes,
>>>> -
>>>> T->getExtProtoInfo());
>>>> + ParamTypes.begin()) || EPIChanged) {
>>>> + Result = getDerived().RebuildFunctionProtoType(ResultType,
>>>> ParamTypes, EPI);
>>>> if (Result.isNull())
>>>> return QualType();
>>>> }
>>>> @@ -4590,6 +4607,107 @@ TreeTransform<Derived>::TransformFunctio
>>>> }
>>>>
>>>> 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) {
>>>> @@ -8895,9 +9013,13 @@ TreeTransform<Derived>::TransformLambdaE
>>>> // transformed parameters.
>>>>
>>>> TypeLocBuilder NewCallOpTLBuilder;
>>>> - QualType NewCallOpType =
>>>> TransformFunctionProtoType(NewCallOpTLBuilder,
>>>> - OldCallOpFPTL,
>>>> - nullptr, 0);
>>>> + SmallVector<QualType, 4> ExceptionStorage;
>>>> + QualType NewCallOpType = TransformFunctionProtoType(
>>>> + NewCallOpTLBuilder, OldCallOpFPTL, nullptr, 0,
>>>> + [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
>>>> + return TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(),
>>>> ESI,
>>>> + ExceptionStorage, Changed);
>>>> + });
>>>> 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/CXX/except/except.spec/p1.cpp (original)
>>>> +++ cfe/trunk/test/CXX/except/except.spec/p1.cpp Wed Sep 17 18:57:05
>>>> 2014
>>>> @@ -77,5 +77,12 @@ 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}}
>>>> };
>>>>
>>>> - void g() { A<0>::f(); } // expected-note{{in instantiation of
>>>> exception specification for 'f' requested here}}
>>>> + 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}}
>>>> + }
>>>> }
>>>>
>>>> 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
>>>> (original)
>>>> +++ cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
>>>> Wed Sep 17 18:57:05 2014
>>>> @@ -137,3 +137,37 @@ 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=217995&r1=217994&r2=217995&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp
>>>> (original)
>>>> +++ cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp Wed Sep
>>>> 17 18:57:05 2014
>>>> @@ -1,5 +1,7 @@
>>>> -// RUN: %clang_cc1 -fsyntax-only -verify %s
>>>> +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -verify %s -DERRORS
>>>> +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -emit-llvm-only %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}}
>>>>
>>>> @@ -7,3 +9,20 @@ 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}}
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>
>>>
>>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140918/33a18f30/attachment.html>
More information about the cfe-commits
mailing list