@@ -969,8 +969,30 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
969969 // equivalence.
970970 LocalInstantiationScope ScopeForParameters (S);
971971 if (auto *FD = DeclInfo.getDecl ()->getAsFunction ())
972- for (auto *PVD : FD->parameters ())
973- ScopeForParameters.InstantiatedLocal (PVD, PVD);
972+ for (auto *PVD : FD->parameters ()) {
973+ if (!PVD->isParameterPack ()) {
974+ ScopeForParameters.InstantiatedLocal (PVD, PVD);
975+ continue ;
976+ }
977+ // This is hacky: we're mapping the parameter pack to a size-of-1 argument
978+ // to avoid building SubstTemplateTypeParmPackTypes for
979+ // PackExpansionTypes. The SubstTemplateTypeParmPackType node would
980+ // otherwise reference the AssociatedDecl of the template arguments, which
981+ // is, in this case, the template declaration.
982+ //
983+ // However, as we are in the process of comparing potential
984+ // re-declarations, the canonical declaration is the declaration itself at
985+ // this point. So if we didn't expand these packs, we would end up with an
986+ // incorrect profile difference because we will be profiling the
987+ // canonical types!
988+ //
989+ // FIXME: Improve the "no-transform" machinery in FindInstantiatedDecl so
990+ // that we can eliminate the Scope in the cases where the declarations are
991+ // not necessarily instantiated. It would also benefit the noexcept
992+ // specifier comparison.
993+ ScopeForParameters.MakeInstantiatedLocalArgPack (PVD);
994+ ScopeForParameters.InstantiatedLocalPackArg (PVD, PVD);
995+ }
974996
975997 std::optional<Sema::CXXThisScopeRAII> ThisScope;
976998
0 commit comments