[all-commits] [llvm/llvm-project] c2d7e9: [clang] Fix non-deterministic infinite recursion.....
Alejandro Álvarez Ayllón via All-commits
all-commits at lists.llvm.org
Tue Dec 10 00:18:03 PST 2024
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: c2d7e96cde10a0da6fff8dde9473b508f0ef29ba
https://github.com/llvm/llvm-project/commit/c2d7e96cde10a0da6fff8dde9473b508f0ef29ba
Author: Alejandro Álvarez Ayllón <alejandro.alvarez at sonarsource.com>
Date: 2024-12-10 (Tue, 10 Dec 2024)
Changed paths:
M clang/include/clang/AST/ASTContext.h
M clang/include/clang/AST/Type.h
M clang/lib/AST/ASTContext.cpp
A clang/test/Parser/gh110231.cpp
Log Message:
-----------
[clang] Fix non-deterministic infinite recursion... (#118288)
...in `ASTContext::getAutoTypeInternal`
Given
```cpp
template < typename >
concept C1 = true;
template < typename , auto >
concept C2 = true;
template < C1 auto V, C2< V > auto>
struct S;
```
Both `C1 auto V` and `C2<V> auto` end on the set `AutoType`, the former
being a template parameter for the latter.
Since the hashing is not deterministic (i.e., pointers are hashed),
every now and then, both will end on the same bucket. Given that
`FoldingSet` recomputes the `FoldingSetID` for each node in the target
bucket on lookup, this triggers an infinite recursion:
1. Look for `X` in `AutoTypes`
2. Let's assume it would be in bucket N, so it iterates over nodes in
that bucket. Let's assume the first is `C2<V> auto`.
3. Computes the `FoldingSetID` for this one, which requires the profile
of its template parameters, so they are visited.
4. In some frames below, we end on the same `FoldingSet`, and, by
chance, `C1 auto V` would be in bucket N too.
5. But the first node in the bucket is `C2<V> auto` for which we need to
profile `C1 auto V`
6. ... stack overflow!
No step individually does anything wrong, but in general, `FoldingSet`
seems not to be re-entrant, and this fact is hidden behind many nested
calls.
With this change, we store the `AutoType`s inside a `DenseMap` instead.
The `FoldingSetID` is computed once only and then kept as the map's key,
avoiding the need to do recursive lookups.
We also now make sure the key for the inserted `AutoType` is the same as
the key used for lookup. Before, this was not the case, and it caused
also non-deterministic parsing errors.
Fixes https://github.com/llvm/llvm-project/issues/110231
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