Skip to content

Conversation

@zyn0217
Copy link
Contributor

@zyn0217 zyn0217 commented Oct 28, 2025

The NormalizationCache may be inserted recursively when normalizing template arguments with non-dependent default arguments. Since the ADT doesn't preserve iterator validity, this caused undefined behavior.

This is a regression on trunk so there is no release note.

Fixes #165238

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 28, 2025

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

Changes

The NormalizationCache may be inserted recursively when normalizing template arguments with non-dependent default arguments. Since the ADT doesn't preserve iterator validity, this caused undefined behavior.

We convert it to std::map where the insert operation doesn't invalidate iterators, than calling find() twice for performance concerns.

This is a regression on trunk so there is no release note.

Fixes #165238


Full diff: https://github.com/llvm/llvm-project/pull/165352.diff

2 Files Affected:

  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/test/SemaTemplate/concepts.cpp (+26)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 52904c72d1cfc..031d1811c5c27 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14941,7 +14941,7 @@ class Sema final : public SemaBase {
   /// constrained declarations). If an error occurred while normalizing the
   /// associated constraints of the template or concept, nullptr will be cached
   /// here.
-  llvm::DenseMap<ConstrainedDeclOrNestedRequirement, NormalizedConstraint *>
+  std::map<ConstrainedDeclOrNestedRequirement, NormalizedConstraint *>
       NormalizationCache;
 
   /// Cache whether the associated constraint of a declaration
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index becf5467a1b61..c90af41a09468 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1632,3 +1632,29 @@ void fn3() {
 }
 
 }
+
+namespace GH165238 {
+
+namespace std {
+template <typename, typename _Tp>
+concept output_iterator = requires(_Tp __t) { __t; };
+template <typename _Out> struct basic_format_context {
+  static_assert(output_iterator<_Out, int>);
+  using char_type = _Out;
+};
+template <typename> class basic_format_parse_context;
+template <typename, typename _Context, typename _Formatter,
+          typename = basic_format_parse_context<typename _Context::char_type>>
+concept __parsable_with = requires(_Formatter __f) { __f; };
+template <typename _Tp, typename _CharT,
+          typename _Context = basic_format_context<_CharT>>
+concept __formattable_impl = __parsable_with<_Tp, _Context, _Context>;
+template <typename _Tp, typename _CharT>
+concept formattable = __formattable_impl<_Tp, _CharT>;
+} // namespace std
+struct {
+  void operator()(std::formattable<char> auto);
+} call;
+void foo() { call(""); }
+
+}

@zyn0217 zyn0217 marked this pull request as draft October 28, 2025 05:18
The NormalizationCache may be inserted recursively when normalizing
template arguments with non-dependent default arguments. Since the ADT
doesn't preserve iterator validity, this caused undefined behavior.
@zyn0217 zyn0217 force-pushed the post-parameter-mapping-8 branch from 1cd7eb4 to 855c54c Compare October 28, 2025 05:47
@zyn0217 zyn0217 marked this pull request as ready for review October 28, 2025 05:48
@zyn0217 zyn0217 merged commit 2984a8d into llvm:main Oct 28, 2025
12 of 14 checks passed
@zyn0217 zyn0217 deleted the post-parameter-mapping-8 branch October 28, 2025 07:15
@zwuis zwuis added the skip-precommit-approval PR for CI feedback, not intended for review label Oct 28, 2025
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
…he (llvm#165352)

The NormalizationCache may be inserted recursively when normalizing
template arguments with non-dependent default arguments. Since the ADT
doesn't preserve iterator validity, this caused undefined behavior.

This is a regression on trunk so there is no release note.

Fixes llvm#165238
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
…he (llvm#165352)

The NormalizationCache may be inserted recursively when normalizing
template arguments with non-dependent default arguments. Since the ADT
doesn't preserve iterator validity, this caused undefined behavior.

This is a regression on trunk so there is no release note.

Fixes llvm#165238
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category skip-precommit-approval PR for CI feedback, not intended for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[clang] Crash in SemaConcept.cpp / Sema::getNormalizedAssociatedConstraints (invalidated iterator?)

3 participants