Skip to content

Commit 45a2d49

Browse files
committed
[FOLD] simplify SubstituteExceptionSpecWithoutEvaluation
1 parent cac5401 commit 45a2d49

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

clang/lib/Sema/SemaExceptionSpec.cpp

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -523,18 +523,19 @@ static const Expr *SubstituteExceptionSpecWithoutEvaluation(
523523
Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo,
524524
const Expr *ExceptionSpec) {
525525
MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
526-
DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(),
527-
/*Final=*/false, /*Innermost=*/std::nullopt,
528-
/*RelativeToPrimary=*/true, /*ForConstraintInstantiation=*/true);
526+
DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), /*Final=*/false,
527+
/*Innermost=*/std::nullopt,
528+
/*RelativeToPrimary=*/true,
529+
/*ForConstraintInstantiation=*/true);
529530

530-
if (!MLTAL.getNumSubstitutedLevels())
531+
if (MLTAL.getNumSubstitutedLevels() == 0)
531532
return ExceptionSpec;
532533

533534
Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false);
534535

536+
auto *FD = const_cast<FunctionDecl *>(DeclInfo.getDecl()->getAsFunction());
535537
Sema::InstantiatingTemplate Inst(
536-
S, DeclInfo.getLocation(),
537-
const_cast<FunctionDecl *>(DeclInfo.getDecl()->getAsFunction()),
538+
S, DeclInfo.getLocation(), FD,
538539
Sema::InstantiatingTemplate::ExceptionSpecification());
539540
if (Inst.isInvalid())
540541
return nullptr;
@@ -544,11 +545,31 @@ static const Expr *SubstituteExceptionSpecWithoutEvaluation(
544545
// this may happen while we're comparing two templates' constraint
545546
// equivalence.
546547
LocalInstantiationScope ScopeForParameters(S);
547-
if (auto *FD = DeclInfo.getDecl()->getAsFunction())
548-
for (auto *PVD : FD->parameters())
549-
ScopeForParameters.InstantiatedLocal(PVD, PVD);
550548

551-
std::optional<Sema::CXXThisScopeRAII> ThisScope;
549+
for (auto *PVD : FD->parameters()) {
550+
if (!PVD->isParameterPack()) {
551+
ScopeForParameters.InstantiatedLocal(PVD, PVD);
552+
continue;
553+
}
554+
// This is hacky: we're mapping the parameter pack to a size-of-1 argument
555+
// to avoid building SubstTemplateTypeParmPackTypes for
556+
// PackExpansionTypes. The SubstTemplateTypeParmPackType node would
557+
// otherwise reference the AssociatedDecl of the template arguments, which
558+
// is, in this case, the template declaration.
559+
//
560+
// However, as we are in the process of comparing potential
561+
// re-declarations, the canonical declaration is the declaration itself at
562+
// this point. So if we didn't expand these packs, we would end up with an
563+
// incorrect profile difference because we will be profiling the
564+
// canonical types!
565+
//
566+
// FIXME: Improve the "no-transform" machinery in FindInstantiatedDecl so
567+
// that we can eliminate the Scope in the cases where the declarations are
568+
// not necessarily instantiated. It would also benefit the noexcept
569+
// specifier comparison.
570+
ScopeForParameters.MakeInstantiatedLocalArgPack(PVD);
571+
ScopeForParameters.InstantiatedLocalPackArg(PVD, PVD);
572+
}
552573

553574
// See TreeTransform::RebuildTemplateSpecializationType. A context scope is
554575
// essential for having an injected class as the canonical type for a template
@@ -557,12 +578,12 @@ static const Expr *SubstituteExceptionSpecWithoutEvaluation(
557578
// template specializations can be profiled to the same value, which makes it
558579
// possible that e.g. constraints involving C<Class<T>> and C<Class> are
559580
// perceived identical.
560-
std::optional<Sema::ContextRAII> ContextScope;
561-
if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext())) {
562-
ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
563-
ContextScope.emplace(S, const_cast<DeclContext *>(cast<DeclContext>(RD)),
564-
/*NewThisContext=*/false);
565-
}
581+
Sema::ContextRAII ContextScope(S, FD);
582+
583+
auto *MD = dyn_cast<CXXMethodDecl>(FD);
584+
Sema::CXXThisScopeRAII ThisScope(
585+
S, MD ? MD->getParent() : nullptr,
586+
MD ? MD->getMethodQualifiers() : Qualifiers{}, MD != nullptr);
566587

567588
EnterExpressionEvaluationContext ConstantEvaluated(
568589
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);

0 commit comments

Comments
 (0)