aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2023-12-22 13:11:27 +0100
committerGitHub <noreply@github.com>2023-12-22 13:11:27 +0100
commit86dc6e15f22610bbb53eb4efda0a178ecefc933a (patch)
treec97c34963bee80f3e9f272d11caab36ee8298226
parent95b423e44f6f35651bb1e7d4f6e0591df71360af (diff)
downloadllvm-86dc6e15f22610bbb53eb4efda0a178ecefc933a.zip
llvm-86dc6e15f22610bbb53eb4efda0a178ecefc933a.tar.gz
llvm-86dc6e15f22610bbb53eb4efda0a178ecefc933a.tar.bz2
[Sema] Fix crash on invalid code with parenthesized aggregate initialization (#76232)
Fixes #76228. Use the same logic as braced init lists, also adds a test that puts incomplete types in various positions to check for regressions in the future.
-rw-r--r--clang/lib/Sema/SemaInit.cpp8
-rw-r--r--clang/test/SemaCXX/crash-GH76228.cpp28
2 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d5ba7fd..f768d27 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5512,6 +5512,14 @@ static void TryOrBuildParenListInitialization(
} else if (auto *RT = Entity.getType()->getAs<RecordType>()) {
bool IsUnion = RT->isUnionType();
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ if (RD->isInvalidDecl()) {
+ // Exit early to avoid confusion when processing members.
+ // We do the same for braced list initialization in
+ // `CheckStructUnionTypes`.
+ Sequence.SetFailed(
+ clang::InitializationSequence::FK_ParenthesizedListInitFailed);
+ return;
+ }
if (!IsUnion) {
for (const CXXBaseSpecifier &Base : RD->bases()) {
diff --git a/clang/test/SemaCXX/crash-GH76228.cpp b/clang/test/SemaCXX/crash-GH76228.cpp
new file mode 100644
index 0000000..33a9395
--- /dev/null
+++ b/clang/test/SemaCXX/crash-GH76228.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+// Check we don't crash on incomplete members and bases when handling parenthesized initialization.
+class incomplete; // expected-note@-0 3 {{forward declaration of 'incomplete'}}
+struct foo {
+ int a;
+ incomplete b;
+ // expected-error@-1 {{incomplete type}}
+};
+foo a1(0);
+
+struct one_int {
+ int a;
+};
+struct bar : one_int, incomplete {};
+// expected-error@-1 {{incomplete type}}
+bar a2(0);
+
+incomplete a3[3](1,2,3);
+// expected-error@-1 {{incomplete type}}
+
+struct qux : foo {
+};
+qux a4(0);
+
+struct fred {
+ foo a[3];
+};
+fred a5(0);