@@ -684,10 +684,6 @@ class TreeTransform {
684684 Qualifiers ThisTypeQuals,
685685 Fn TransformExceptionSpec);
686686
687- template <typename Fn>
688- QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL,
689- Fn TransformModifiedType);
690-
691687 bool TransformExceptionSpec(SourceLocation Loc,
692688 FunctionProtoType::ExceptionSpecInfo &ESI,
693689 SmallVectorImpl<QualType> &Exceptions,
@@ -7373,11 +7369,10 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
73737369}
73747370
73757371template <typename Derived>
7376- template <typename Fn>
7377- QualType TreeTransform<Derived>::TransformAttributedType(
7378- TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
7372+ QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7373+ AttributedTypeLoc TL) {
73797374 const AttributedType *oldType = TL.getTypePtr();
7380- QualType modifiedType = TransformModifiedTypeFn (TLB, TL.getModifiedLoc());
7375+ QualType modifiedType = getDerived().TransformType (TLB, TL.getModifiedLoc());
73817376 if (modifiedType.isNull())
73827377 return QualType();
73837378
@@ -7392,12 +7387,27 @@ QualType TreeTransform<Derived>::TransformAttributedType(
73927387 // FIXME: dependent operand expressions?
73937388 if (getDerived().AlwaysRebuild() ||
73947389 modifiedType != oldType->getModifiedType()) {
7395- TypeLocBuilder AuxiliaryTLB;
7396- AuxiliaryTLB.reserve(TL.getFullDataSize());
7397- QualType equivalentType =
7398- getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7399- if (equivalentType.isNull())
7400- return QualType();
7390+ // If the equivalent type is equal to the modified type, we don't want to
7391+ // transform it as well because:
7392+ //
7393+ // 1. The transformation would yield the same result and is therefore
7394+ // superfluous, and
7395+ //
7396+ // 2. Transforming the same type twice can cause problems, e.g. if it
7397+ // is a FunctionProtoType, we may end up instantiating the function
7398+ // parameters twice, which causes an assertion since the parameters
7399+ // are already bound to their counterparts in the template for this
7400+ // instantiation.
7401+ //
7402+ QualType equivalentType = modifiedType;
7403+ if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7404+ TypeLocBuilder AuxiliaryTLB;
7405+ AuxiliaryTLB.reserve(TL.getFullDataSize());
7406+ equivalentType =
7407+ getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7408+ if (equivalentType.isNull())
7409+ return QualType();
7410+ }
74017411
74027412 // Check whether we can add nullability; it is only represented as
74037413 // type sugar, and therefore cannot be diagnosed in any other way.
@@ -7421,15 +7431,6 @@ QualType TreeTransform<Derived>::TransformAttributedType(
74217431 return result;
74227432}
74237433
7424- template <typename Derived>
7425- QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7426- AttributedTypeLoc TL) {
7427- return getDerived().TransformAttributedType(
7428- TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7429- return getDerived().TransformType(TLB, ModifiedLoc);
7430- });
7431- }
7432-
74337434template <typename Derived>
74347435QualType TreeTransform<Derived>::TransformCountAttributedType(
74357436 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
@@ -14774,63 +14775,29 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
1477414775 TPL->containsUnexpandedParameterPack();
1477514776 }
1477614777
14777- // Transform the type of the original lambda's call operator.
14778- // The transformation MUST be done in the CurrentInstantiationScope since
14779- // it introduces a mapping of the original to the newly created
14780- // transformed parameters.
14781- TypeSourceInfo *NewCallOpTSI = nullptr;
14782- {
14783- auto OldCallOpTypeLoc =
14784- E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
14785-
14786- auto TransformFunctionProtoTypeLoc =
14787- [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
14788- SmallVector<QualType, 4> ExceptionStorage;
14789- return this->TransformFunctionProtoType(
14790- TLB, FPTL, nullptr, Qualifiers(),
14791- [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
14792- return TransformExceptionSpec(FPTL.getBeginLoc(), ESI,
14793- ExceptionStorage, Changed);
14794- });
14795- };
14796-
14797- QualType NewCallOpType;
14798- TypeLocBuilder NewCallOpTLBuilder;
14799-
14800- if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
14801- NewCallOpType = this->TransformAttributedType(
14802- NewCallOpTLBuilder, ATL,
14803- [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
14804- return TransformFunctionProtoTypeLoc(
14805- TLB, TL.castAs<FunctionProtoTypeLoc>());
14806- });
14807- } else {
14808- auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
14809- NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
14810- }
14811-
14812- if (NewCallOpType.isNull())
14813- return ExprError();
14814- LSI->ContainsUnexpandedParameterPack |=
14815- NewCallOpType->containsUnexpandedParameterPack();
14816- NewCallOpTSI =
14817- NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
14818- }
14778+ TypeLocBuilder NewCallOpTLBuilder;
14779+ TypeLoc OldCallOpTypeLoc =
14780+ E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
14781+ QualType NewCallOpType =
14782+ getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
14783+ if (NewCallOpType.isNull())
14784+ return ExprError();
14785+ LSI->ContainsUnexpandedParameterPack |=
14786+ NewCallOpType->containsUnexpandedParameterPack();
14787+ TypeSourceInfo *NewCallOpTSI =
14788+ NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
1481914789
14820- ArrayRef<ParmVarDecl *> Params;
14821- if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
14822- Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
14823- } else {
14824- auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
14825- Params = FPTL.getParams();
14826- }
14790+ // The type may be an AttributedType or some other kind of sugar;
14791+ // get the actual underlying FunctionProtoType.
14792+ auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
14793+ assert(FPTL && "Not a FunctionProtoType?");
1482714794
1482814795 getSema().CompleteLambdaCallOperator(
1482914796 NewCallOperator, E->getCallOperator()->getLocation(),
1483014797 E->getCallOperator()->getInnerLocStart(),
1483114798 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
1483214799 E->getCallOperator()->getConstexprKind(),
14833- E->getCallOperator()->getStorageClass(), Params ,
14800+ E->getCallOperator()->getStorageClass(), FPTL.getParams() ,
1483414801 E->hasExplicitResultType());
1483514802
1483614803 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
0 commit comments