Skip to content

Commit 1cd7eb4

Browse files
committed
[Clang] Fix an iterator invalidation bug in concept normalization cache
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 std::map where the insert operation doesn't invalidate iterators.
1 parent 76e2963 commit 1cd7eb4

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14941,7 +14941,7 @@ class Sema final : public SemaBase {
1494114941
/// constrained declarations). If an error occurred while normalizing the
1494214942
/// associated constraints of the template or concept, nullptr will be cached
1494314943
/// here.
14944-
llvm::DenseMap<ConstrainedDeclOrNestedRequirement, NormalizedConstraint *>
14944+
std::map<ConstrainedDeclOrNestedRequirement, NormalizedConstraint *>
1494514945
NormalizationCache;
1494614946

1494714947
/// Cache whether the associated constraint of a declaration

clang/test/SemaTemplate/concepts.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,3 +1632,29 @@ void fn3() {
16321632
}
16331633

16341634
}
1635+
1636+
namespace GH165238 {
1637+
1638+
namespace std {
1639+
template <typename, typename _Tp>
1640+
concept output_iterator = requires(_Tp __t) { __t; };
1641+
template <typename _Out> struct basic_format_context {
1642+
static_assert(output_iterator<_Out, int>);
1643+
using char_type = _Out;
1644+
};
1645+
template <typename> class basic_format_parse_context;
1646+
template <typename, typename _Context, typename _Formatter,
1647+
typename = basic_format_parse_context<typename _Context::char_type>>
1648+
concept __parsable_with = requires(_Formatter __f) { __f; };
1649+
template <typename _Tp, typename _CharT,
1650+
typename _Context = basic_format_context<_CharT>>
1651+
concept __formattable_impl = __parsable_with<_Tp, _Context, _Context>;
1652+
template <typename _Tp, typename _CharT>
1653+
concept formattable = __formattable_impl<_Tp, _CharT>;
1654+
} // namespace std
1655+
struct {
1656+
void operator()(std::formattable<char> auto);
1657+
} call;
1658+
void foo() { call(""); }
1659+
1660+
}

0 commit comments

Comments
 (0)