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

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 19 01:18:01 PST 2023


https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/72428

>From e182e764778eb137f465812270fcdf03d0fe2da1 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 15 Nov 2023 20:31:12 +0100
Subject: [PATCH 1/3] [clang][AST] Invalidate DecompositionDecl if it has
 invalid initializer.

Fix #67495, #72198
---
 clang/lib/Sema/SemaDecl.cpp                     |  9 +++++++++
 clang/test/AST/ast-dump-invalid-initialized.cpp | 15 ++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index edf44bbc52119b..13cd4d9644d727 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13576,6 +13576,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 concrete type (e.g.
+      //    `int [a, b] = 1;`), and the initializer is invalid;
+      // Case 1) is already handled earlier in this function.
+      if (llvm::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 1c374ae716a9db..a71a02f0f60039 100644
--- a/clang/test/AST/ast-dump-invalid-initialized.cpp
+++ b/clang/test/AST/ast-dump-invalid-initialized.cpp
@@ -24,4 +24,17 @@ void test() {
   auto b4 = A(1);
   // CHECK: `-VarDecl {{.*}} invalid b5 'auto'
   auto b5 = A{1};
-}
\ No newline at end of file
+}
+
+void pr72198() {
+  // CHECK: DecompositionDecl {{.*}} invalid 'int'
+  int [_, b] = {0, 0};
+  [b]{};
+}
+
+int get_point();
+void pr67495() {
+  // CHECK: DecompositionDecl {{.*}} invalid 'int &'
+  auto& [x, y] = get_point();
+  [x, y] {};
+}

>From 94a6db1d1f513af792b1764961c897d44b9cba5f Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Fri, 17 Nov 2023 10:54:33 +0100
Subject: [PATCH 2/3] Address comments.

---
 clang/lib/Sema/SemaDecl.cpp                     | 6 +++---
 clang/test/AST/ast-dump-invalid-initialized.cpp | 6 ++++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 13cd4d9644d727..c7ace117e8bced 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13580,9 +13580,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
       // 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 concrete type (e.g.
-      //    `int [a, b] = 1;`), and the initializer is invalid;
-      // Case 1) is already handled earlier in this function.
+      //  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 (llvm::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 a71a02f0f60039..7fcbc41a7be400 100644
--- a/clang/test/AST/ast-dump-invalid-initialized.cpp
+++ b/clang/test/AST/ast-dump-invalid-initialized.cpp
@@ -26,15 +26,17 @@ void test() {
   auto b5 = A{1};
 }
 
-void pr72198() {
+void GH72198() {
   // CHECK: DecompositionDecl {{.*}} invalid 'int'
   int [_, b] = {0, 0};
   [b]{};
 }
 
+namespace GH67495 {
 int get_point();
-void pr67495() {
+void f() {
   // CHECK: DecompositionDecl {{.*}} invalid 'int &'
   auto& [x, y] = get_point();
   [x, y] {};
 }
+}

>From ff9d909135edcc5851b234663fe392fe85070a61 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 19 Dec 2023 10:11:50 +0100
Subject: [PATCH 3/3] Add release note.

---
 clang/docs/ReleaseNotes.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index edb97347f07716..d0a81a44a650e4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -686,6 +686,9 @@ Bug Fixes in This Version
 - Fix an issue where clang doesn't respect detault template arguments that
   are added in a later redeclaration for CTAD.
   Fixes (#69987 <https://github.com/llvm/llvm-project/issues/69987>`_)
+- 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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^



More information about the cfe-commits mailing list