https://github.com/ricejasonf created https://github.com/llvm/llvm-project/pull/135129
Fixes #134882 Consider ``` struct foo { char a; int b; }; constexpr foo t{'a', 1}; constexpr auto [...m] = t; ``` Without the `constexpr` qualifier, the decomposition declaration just happens to not crash in the call to `DeclMustBeEmitted` because it returns early because of its "discardable gval linkage". So, the fix is in `flat_bindings` where we cannot assume the pack binding is valid. There is also a fix along the same vein from a suggestion made by @shafik. The tests are still building on my machine, but I thought I would submit this to get eyes on it earlier since it is trivial. >From 27290e3c7dc2a36a33e4582758d875704c7cbe33 Mon Sep 17 00:00:00 2001 From: Jason Rice <ricejas...@gmail.com> Date: Wed, 9 Apr 2025 21:31:00 -0700 Subject: [PATCH] [Clang][P1061] Fix invalid pack binding crash --- clang/include/clang/AST/DeclCXX.h | 2 +- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 ++--- clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 56cec07ec0293..ba6d87f8158ab 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 e0f7ccc4674d8..4f7410c9bf0d8 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..1818dc699c71c 100644 --- a/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp +++ b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp @@ -8,4 +8,10 @@ void decompose_array() { // cxx23-warning@+2 {{structured binding packs are a C++2c extension}} // nontemplate-error@+1 {{pack declaration outside of template}} auto [x, ...rest, y] = arr; + + // cxx26-warning@+4 {{structured binding packs are incompatible with C++ standards before C++2c}} + // cxx23-warning@+3 {{structured binding packs are a C++2c extension}} + // nontemplate-error@+2 {{decomposition declaration cannot be declared 'constexpr'}} + // nontemplate-error@+1 {{pack declaration outside of template}} + constexpr auto [x, ...rest, y] = arr; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits