[clang] 8f7fdd9 - [clang][AST] Invalidate DecompositionDecl if it has invalid initializer. (#72428)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 17 03:11:21 PST 2024


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] {};
+}
+}


        


More information about the cfe-commits mailing list