[clang] 2f29829 - [Clang][P1061] Fix invalid pack binding crash (#135129)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 10 17:12:15 PDT 2025


Author: Jason Rice
Date: 2025-04-11T08:12:11+08:00
New Revision: 2f298294759307e532dcce50549534cbe8ba6561

URL: https://github.com/llvm/llvm-project/commit/2f298294759307e532dcce50549534cbe8ba6561
DIFF: https://github.com/llvm/llvm-project/commit/2f298294759307e532dcce50549534cbe8ba6561.diff

LOG: [Clang][P1061] Fix invalid pack binding crash (#135129)

Added: 
    

Modified: 
    clang/include/clang/AST/DeclCXX.h
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index f0e25c4105f87..49d48bf711f33 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -4281,7 +4281,7 @@ class DecompositionDecl final
         [](BindingDecl *BD) { return BD->isParameterPack(); });
 
     Bindings = Bindings.drop_front(BeforePackBindings.size());
-    if (!Bindings.empty()) {
+    if (!Bindings.empty() && Bindings.front()->getBinding()) {
       PackBindings = Bindings.front()->getBindingPackDecls();
       Bindings = Bindings.drop_front();
     }

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8b8db36c10771..3f619b3fb3daa 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1597,11 +1597,10 @@ Decl *TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) {
   auto *NewDD = cast_if_present<DecompositionDecl>(
       VisitVarDecl(D, /*InstantiatingVarTemplate=*/false, &NewBindingArray));
 
-  if (!NewDD || NewDD->isInvalidDecl())
+  if (!NewDD || NewDD->isInvalidDecl()) {
     for (auto *NewBD : NewBindings)
       NewBD->setInvalidDecl();
-
-  if (OldBindingPack) {
+  } else if (OldBindingPack) {
     // Mark the bindings in the pack as instantiated.
     auto Bindings = NewDD->bindings();
     BindingDecl *NewBindingPack = *llvm::find_if(

diff  --git a/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp
index ea94757dc66b6..a4f0bcdb4270b 100644
--- a/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp
+++ b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp
@@ -3,9 +3,15 @@
 // RUN: %clang_cc1 -std=c++23 -verify=cxx23,nontemplate -fsyntax-only -Wc++26-extensions %s
 
 void decompose_array() {
-  int arr[4] = {1, 2, 3, 6};
+  constexpr int arr[4] = {1, 2, 3, 6};
   // cxx26-warning at +3 {{structured binding packs are incompatible with C++ standards before C++2c}}
   // cxx23-warning at +2 {{structured binding packs are a C++2c extension}}
   // nontemplate-error at +1 {{pack declaration outside of template}}
   auto [x, ...rest, y] = arr;
+
+  // cxx26-warning at +4 {{structured binding packs are incompatible with C++ standards before C++2c}}
+  // cxx23-warning at +3 {{structured binding packs are a C++2c extension}}
+  // nontemplate-error at +2 {{decomposition declaration cannot be declared 'constexpr'}}
+  // nontemplate-error at +1 {{pack declaration outside of template}}
+  constexpr auto [x_c, ...rest_c, y_c] = arr;
 }


        


More information about the cfe-commits mailing list