Author: Haojian Wu Date: 2024-01-17T12:11:16+01:00 New Revision: 8f7fdd94ef19af7b4905b316c253a78219a6038f
URL: https://github.com/llvm/llvm-project/commit/8f7fdd94ef19af7b4905b316c253a78219a6038f DIFF: https://github.com/llvm/llvm-project/commit/8f7fdd94ef19af7b4905b316c253a78219a6038f.diff LOG: [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. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaDecl.cpp clang/test/AST/ast-dump-invalid-initialized.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e45e016b3d66bd1..737302520024515 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -765,6 +765,9 @@ Bug Fixes in This Version Fixes (`#77583 <https://github.com/llvm/llvm-project/issues/77583>`_) - Fix an issue where CTAD fails for function-type/array-type arguments. Fixes (`#51710 <https://github.com/llvm/llvm-project/issues/51710>`_) +- Fix crashes when using the binding decl from an invalid structured binding. + Fixes (`#67495 <https://github.com/llvm/llvm-project/issues/67495>`_) and + (`#72198 <https://github.com/llvm/llvm-project/issues/72198>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b642f38fa628ace..b74ff0b9bfe4c83 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13602,6 +13602,15 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), Args); if (RecoveryExpr.get()) VDecl->setInit(RecoveryExpr.get()); + // In general, for error recovery purposes, the initalizer doesn't play + // part in the valid bit of the declaration. There are a few exceptions: + // 1) if the var decl has a deduced auto type, and the type cannot be + // deduced by an invalid initializer; + // 2) if the var decl is decompsition decl with a non-deduced type, and + // the initialization fails (e.g. `int [a] = {1, 2};`); + // Case 1) was already handled elsewhere. + if (isa<DecompositionDecl>(VDecl)) // Case 2) + VDecl->setInvalidDecl(); return; } diff --git a/clang/test/AST/ast-dump-invalid-initialized.cpp b/clang/test/AST/ast-dump-invalid-initialized.cpp index 1c374ae716a9db5..7fcbc41a7be4001 100644 --- a/clang/test/AST/ast-dump-invalid-initialized.cpp +++ b/clang/test/AST/ast-dump-invalid-initialized.cpp @@ -24,4 +24,19 @@ void test() { auto b4 = A(1); // CHECK: `-VarDecl {{.*}} invalid b5 'auto' auto b5 = A{1}; -} \ No newline at end of file +} + +void GH72198() { + // CHECK: DecompositionDecl {{.*}} invalid 'int' + int [_, b] = {0, 0}; + [b]{}; +} + +namespace GH67495 { +int get_point(); +void f() { + // CHECK: DecompositionDecl {{.*}} invalid 'int &' + auto& [x, y] = get_point(); + [x, y] {}; +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits