@@ -523,18 +523,19 @@ static const Expr *SubstituteExceptionSpecWithoutEvaluation(
523
523
Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo,
524
524
const Expr *ExceptionSpec) {
525
525
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 );
529
530
530
- if (! MLTAL.getNumSubstitutedLevels ())
531
+ if (MLTAL.getNumSubstitutedLevels () == 0 )
531
532
return ExceptionSpec;
532
533
533
534
Sema::SFINAETrap SFINAE (S, /* AccessCheckingSFINAE=*/ false );
534
535
536
+ auto *FD = const_cast <FunctionDecl *>(DeclInfo.getDecl ()->getAsFunction ());
535
537
Sema::InstantiatingTemplate Inst (
536
- S, DeclInfo.getLocation (),
537
- const_cast <FunctionDecl *>(DeclInfo.getDecl ()->getAsFunction ()),
538
+ S, DeclInfo.getLocation (), FD,
538
539
Sema::InstantiatingTemplate::ExceptionSpecification ());
539
540
if (Inst.isInvalid ())
540
541
return nullptr ;
@@ -544,11 +545,31 @@ static const Expr *SubstituteExceptionSpecWithoutEvaluation(
544
545
// this may happen while we're comparing two templates' constraint
545
546
// equivalence.
546
547
LocalInstantiationScope ScopeForParameters (S);
547
- if (auto *FD = DeclInfo.getDecl ()->getAsFunction ())
548
- for (auto *PVD : FD->parameters ())
549
- ScopeForParameters.InstantiatedLocal (PVD, PVD);
550
548
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
+ }
552
573
553
574
// See TreeTransform::RebuildTemplateSpecializationType. A context scope is
554
575
// essential for having an injected class as the canonical type for a template
@@ -557,12 +578,12 @@ static const Expr *SubstituteExceptionSpecWithoutEvaluation(
557
578
// template specializations can be profiled to the same value, which makes it
558
579
// possible that e.g. constraints involving C<Class<T>> and C<Class> are
559
580
// 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 );
566
587
567
588
EnterExpressionEvaluationContext ConstantEvaluated (
568
589
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
0 commit comments