[llvm-branch-commits] [clang] [clang] fix transformation of subst constant template parameter nodes (PR #160777)
Corentin Jabot via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Sep 26 00:32:39 PDT 2025
================
@@ -16289,20 +16289,68 @@ TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
IndexExpr.get(), ExpandedExprs, FullySubstituted);
}
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
- SubstNonTypeTemplateParmPackExpr *E) {
- // Default behavior is to do nothing with this transformation.
- return E;
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
+ SubstNonTypeTemplateParmPackExpr *E) {
+ if (!getSema().ArgPackSubstIndex)
+ // We aren't expanding the parameter pack, so just return ourselves.
+ return E;
+
+ TemplateArgument Pack = E->getArgumentPack();
+ TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Pack);
+ return SemaRef.BuildSubstNonTypeTemplateParmExpr(
+ E->getAssociatedDecl(), E->getParameterPack(),
+ E->getParameterPackLocation(), Arg, SemaRef.getPackIndex(Pack),
+ E->getFinal());
}
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
- SubstNonTypeTemplateParmExpr *E) {
- // Default behavior is to do nothing with this transformation.
- return E;
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
+ SubstNonTypeTemplateParmExpr *E) {
+ Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
+ ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
+ if (Replacement.isInvalid())
+ return true;
+
+ Decl *AssociatedDecl =
+ getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
+ if (!AssociatedDecl)
+ return true;
+
+ if (Replacement.get() == OrigReplacement &&
+ AssociatedDecl == E->getAssociatedDecl())
+ return E;
+
+ // If the replacement expression did not change, and the parameter type
+ // did not change, we can skip the semantic action because it would
+ // produce the same result anyway.
+ auto *Param = cast<NonTypeTemplateParmDecl>(
+ getReplacedTemplateParameterList(AssociatedDecl)
+ ->asArray()[E->getIndex()]);
+ if (QualType ParamType = Param->getType();
+ !SemaRef.Context.hasSameType(ParamType, E->getParameter()->getType()) ||
+ Replacement.get() != OrigReplacement) {
+
+ // When transforming the replacement expression previously, all Sema
+ // specific annotations, such as implicit casts, are erased. Calling the
+ // corresponding sema action is necessary to recover those. Otherwise,
+ // equivalency would be lost on the result.
----------------
cor3ntin wrote:
"the equivalence of the result would be lost" or something like that
https://github.com/llvm/llvm-project/pull/160777
More information about the llvm-branch-commits
mailing list