[all-commits] [llvm/llvm-project] 3669d2: [Clang] Fix ICE in constraint normalization when s...
I via All-commits
all-commits at lists.llvm.org
Wed Mar 11 04:52:52 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 3669d2e4dc2bf21b646a638c6209dea86f94e3d8
https://github.com/llvm/llvm-project/commit/3669d2e4dc2bf21b646a638c6209dea86f94e3d8
Author: I <1091761+wx257osn2 at users.noreply.github.com>
Date: 2026-03-11 (Wed, 11 Mar 2026)
Changed paths:
M clang/docs/ReleaseNotes.rst
M clang/lib/Sema/SemaTemplateInstantiate.cpp
M clang/test/SemaCXX/cxx2c-template-template-param.cpp
Log Message:
-----------
[Clang] Fix ICE in constraint normalization when substituting concept template parameters (#184406)
23341c3d139b889e8c46867f8d704ab3c22b51f8 introduced
`SubstituteConceptsInConstraintExpression` to substitute non-dependent
concept template arguments into a concept's constraint expression during
normalization, as part of the P2841R7 implementation
([temp.constr.normal]/1.4).
The `ConstraintExprTransformer` added in that commit overrides
`TransformTemplateArgument` to only transform concept-related arguments
and preserve all others. However, `TransformUnresolvedLookupExpr` called
`Sema::SubstExpr`, which creates a separate `TemplateInstantiator` that
performs full substitution bypassing the selective override entirely.
This caused all template parameters in the constraint expression to be
substituted using the concept's MLTAL. For example, given:
```cpp
template <class A, template <typename...> concept C>
concept maybe_cvref = C<std::remove_cvref_t<A>>;
template <maybe_cvref<std::integral> T, typename U>
auto f0(T&& t, U&& u); // fortunately it passes on Clang 22 due to
// maybe_cvref's first template parameter (A) has
// same kind (type) of f0's first one (T)
template <typename T, maybe_cvref<std::integral> U>
auto f1(T&& t, U&& u); // it causes ICE on Clang 22
```
`C<std::remove_cvref_t<A>>` was fully substituted into
`std::integral<std::remove_cvref_t<U>>`, where `U` refers to `f1`'s
parameter at depth 0, index 1. When `SubstituteParameterMappings` later
applied the concept's MLTAL, it resolved `U`
(`clang::TemplateArgument::Type`) at (0,1) to `std::integral`
(`clang::TemplateArgument::Template`) instead of the intended type
parameter, causing an ICE due to argument kind mismatch.
Fix this by resolving the concept declaration directly from the MLTAL
and routing template arguments through `ConstraintExprTransformer`'s own
`TransformTemplateArguments`, preserving non-concept arguments
correctly.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list