https://github.com/mizvekov created https://github.com/llvm/llvm-project/pull/135312
This fixes a regression introduced here: https://github.com/llvm/llvm-project/pull/132748 which was originally reported here: https://github.com/llvm/llvm-project/pull/132748#issuecomment-2791012454 Some time in the clang-20 time frame, we had removed subst* nodes produced from template type alias instantiation. This ended up accidentally fixing an issue where the result from an alias template substitution is mistaken for the substitution of an outer non-alias template, incorrectly applying the unresolved-type production to it. This fixes it by ignoring subst* nodes produced from type aliases. Though builtin templates currently don't place subst* nodes, if we ever decide to place them, this fix should cover them as well. No release notes since this regression was never released. >From 6e734dc11ff5e7e1f8153ffe85ba156aa6efe30d Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Fri, 11 Apr 2025 00:36:46 -0300 Subject: [PATCH] [clang] ItaniumMangle: fix mangling for unresolved types This fixes a regression introduced here: https://github.com/llvm/llvm-project/pull/132748 which was originally reported here: https://github.com/llvm/llvm-project/pull/132748#issuecomment-2791012454 Some time in the clang-20 time frame, we had removed subst* nodes produced from template type alias instantiation. This ended up accidentally fixing an issue where the result from an alias template substitution is mistaken for the susbtitution of an outer non-alias template, incorrectly applying the unresolved-type production to it. This fixes it by ignoring subst* nodes produced from type aliases. Though builtin templates currently don't place subst* nodes, if we ever decide to place them, this fix should cover them as well. No release notes since this regression was never released. --- clang/lib/AST/ItaniumMangle.cpp | 11 ++++++++++- clang/test/CodeGenCXX/mangle.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 8790a5282a96b..c73f040ba1cb7 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2511,7 +2511,6 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, case Type::PackIndexing: case Type::TemplateTypeParm: case Type::UnaryTransform: - case Type::SubstTemplateTypeParm: unresolvedType: // Some callers want a prefix before the mangled type. Out << Prefix; @@ -2524,6 +2523,16 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, // so we return directly. return true; + case Type::SubstTemplateTypeParm: { + auto *ST = cast<SubstTemplateTypeParmType>(Ty); + // If this was replaced from a type alias, this is not substituted + // from an outer template parameter, so it's not an unresolved-type. + if (auto *TD = dyn_cast<TemplateDecl>(ST->getAssociatedDecl()); + TD && TD->isTypeAlias()) + return mangleUnresolvedTypeOrSimpleId(ST->getReplacementType(), Prefix); + goto unresolvedType; + } + case Type::Typedef: mangleSourceNameWithAbiTags(cast<TypedefType>(Ty)->getDecl()); break; diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index cf506aff92f0e..f4dc17bc4561e 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -1220,3 +1220,30 @@ namespace test61 { // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE template void f<X>(int, int); } + +namespace test62 { + template <class> struct integral_constant { + static const int value = true; + }; + template <int> struct _OrImpl {}; + template <class _Args> using _Or = _OrImpl<_Args::value>; + template <class _Up> + void f(_Or<integral_constant<_Up>>) {} + // CHECK-LABEL: @_ZN6test621fIiEEvNS_7_OrImplIXsr17integral_constantIT_EE5valueEEE + template void f<int>(_OrImpl<1>); +} // namespace test62 + +namespace test63 { + namespace { + template <class, class> struct integral_constant { + static const int value = true; + }; + template <class, class> struct _And {}; + template <int> struct _OrImpl {}; + template <class _First> using _Or = _OrImpl<_First::value>; + template <class _Up> + void f(_And<integral_constant<int, void>, _Or<integral_constant<_Up, int>>>); + } // namespace + // CHECK-LABEL: @_ZN6test6312_GLOBAL__N_11fIiEEvNS0_4_AndINS0_17integral_constantIivEENS0_7_OrImplIXsr17integral_constantIT_iEE5valueEEEEE + void g() { f<int>({}); } +} // namespace test63 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits