r217995 - Instantiate exception specifications when instantiating function types (other
Yaron Keren
yaron.keren at gmail.com
Thu Sep 18 06:22:07 PDT 2014
I installed Update 3 for Visual C++ 2013, same error as with update 2.
2014-09-18 15:23 GMT+03:00 Yaron Keren <yaron.keren at gmail.com>:
> 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/62f37dd8/attachment.html>
More information about the cfe-commits
mailing list