Skip to content

Commit 6f13c71

Browse files
[clang] fix sema init crashing on initialization sequences (#98102)
We ran into a FE crash and root caused to `ER.get()` on line 5584 here being nullptr. I think this is a result of not checking if ER here is invalid. Example of crash-on-valid C++ https://gist.github.com/yuxuanchen1997/576dce964666f0f8713fccacf5847138 Note that this crash happens only with `-std=c++20`.
1 parent 1f819f0 commit 6f13c71

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,8 @@ Bug Fixes in This Version
813813

814814
- Fixed `static_cast` to array of unknown bound. Fixes (#GH62863).
815815

816+
- Fixed Clang crashing when failing to perform some C++ Initialization Sequences. (#GH98102)
817+
816818
Bug Fixes to Compiler Builtins
817819
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
818820

clang/lib/Sema/SemaInit.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5576,6 +5576,10 @@ static void TryOrBuildParenListInitialization(
55765576
ExprResult ER;
55775577
ER = IS.Perform(S, SubEntity, SubKind,
55785578
Arg ? MultiExprArg(Arg) : std::nullopt);
5579+
5580+
if (ER.isInvalid())
5581+
return false;
5582+
55795583
if (InitExpr)
55805584
*InitExpr = ER.get();
55815585
else

clang/test/SemaCXX/pr98102.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
2+
// expected-no-diagnostics
3+
4+
template <bool v>
5+
struct BC {
6+
static constexpr bool value = v;
7+
};
8+
9+
template <typename T, typename Arg>
10+
struct Constructible : BC<__is_constructible(T, Arg)> {};
11+
12+
template <typename T>
13+
using Requires = T::value;
14+
15+
template <typename T>
16+
struct optional {
17+
template <typename U, Requires<Constructible<T, U>> = true>
18+
optional(U) {}
19+
};
20+
21+
struct MO {};
22+
struct S : MO {};
23+
struct TB {
24+
TB(optional<S>) {}
25+
};
26+
27+
class TD : TB, MO {
28+
using TB::TB;
29+
};
30+
31+
void foo() {
32+
static_assert(Constructible<TD, TD>::value);
33+
}

0 commit comments

Comments
 (0)