Skip to content

Commit 8f7fdd9

Browse files
authored
[clang][AST] Invalidate DecompositionDecl if it has invalid initializer. (#72428)
Fix #67495, #72198 We build ill-formed AST nodes for invalid structured binding. For case `int [_, b] = {0, 0};`, the `DecompositionDecl` is valid, and its children `BindingDecl`s are valid but with a NULL type, this breaks clang invariants in many places, and using these `BindingDecl`s can lead to crashes. This patch fixes them by marking the DecompositionDecl and its children invalid.
1 parent 1fbf533 commit 8f7fdd9

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,9 @@ Bug Fixes in This Version
765765
Fixes (`#77583 <https://github.com/llvm/llvm-project/issues/77583>`_)
766766
- Fix an issue where CTAD fails for function-type/array-type arguments.
767767
Fixes (`#51710 <https://github.com/llvm/llvm-project/issues/51710>`_)
768+
- Fix crashes when using the binding decl from an invalid structured binding.
769+
Fixes (`#67495 <https://github.com/llvm/llvm-project/issues/67495>`_) and
770+
(`#72198 <https://github.com/llvm/llvm-project/issues/72198>`_)
768771

769772
Bug Fixes to Compiler Builtins
770773
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13602,6 +13602,15 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1360213602
CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), Args);
1360313603
if (RecoveryExpr.get())
1360413604
VDecl->setInit(RecoveryExpr.get());
13605+
// In general, for error recovery purposes, the initalizer doesn't play
13606+
// part in the valid bit of the declaration. There are a few exceptions:
13607+
// 1) if the var decl has a deduced auto type, and the type cannot be
13608+
// deduced by an invalid initializer;
13609+
// 2) if the var decl is decompsition decl with a non-deduced type, and
13610+
// the initialization fails (e.g. `int [a] = {1, 2};`);
13611+
// Case 1) was already handled elsewhere.
13612+
if (isa<DecompositionDecl>(VDecl)) // Case 2)
13613+
VDecl->setInvalidDecl();
1360513614
return;
1360613615
}
1360713616

clang/test/AST/ast-dump-invalid-initialized.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,19 @@ void test() {
2424
auto b4 = A(1);
2525
// CHECK: `-VarDecl {{.*}} invalid b5 'auto'
2626
auto b5 = A{1};
27-
}
27+
}
28+
29+
void GH72198() {
30+
// CHECK: DecompositionDecl {{.*}} invalid 'int'
31+
int [_, b] = {0, 0};
32+
[b]{};
33+
}
34+
35+
namespace GH67495 {
36+
int get_point();
37+
void f() {
38+
// CHECK: DecompositionDecl {{.*}} invalid 'int &'
39+
auto& [x, y] = get_point();
40+
[x, y] {};
41+
}
42+
}

0 commit comments

Comments
 (0)