https://github.com/Murthy-Manideep updated https://github.com/llvm/llvm-project/pull/235427
>From 988f161231196f2a0779086d2cc8c2512a72f3bd Mon Sep 17 00:00:00 2001 From: Murthy-Manideep <[email protected]> Date: Sun, 25 Oct 2026 17:19:17 +0530 Subject: [PATCH] Fix extra error message (#222605) --- clang/lib/Sema/SemaDeclCXX.cpp | 14 ++++-- clang/test/Parser/cxx1z-decomposition.cpp | 4 +- clang/test/SemaCXX/GH222605.cpp | 53 +++++++++++++++++++++++ 3 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaCXX/GH222605.cpp diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 0fe0daa71c1bcf..2b9059f24f0214 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -863,10 +863,11 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, // The syntax only allows a single ref-qualifier prior to the decomposition // declarator. No other declarator chunks are permitted. Also check the type // specifier here. - if (DS.getTypeSpecType() != DeclSpec::TST_auto || + bool HasBadDeclarator = D.hasGroupingParens() || D.getNumTypeObjects() > 1 || (D.getNumTypeObjects() == 1 && - D.getTypeObject(0).Kind != DeclaratorChunk::Reference)) { + D.getTypeObject(0).Kind != DeclaratorChunk::Reference); + if (DS.getTypeSpecType() != DeclSpec::TST_auto || HasBadDeclarator) { Diag(Decomp.getLSquareLoc(), (D.hasGroupingParens() || (D.getNumTypeObjects() && @@ -878,7 +879,9 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, // In most cases, there's no actual problem with an explicitly-specified // type, but a function type won't work here, and ActOnVariableDeclarator // shouldn't be called for such a type. - if (R->isFunctionType()) + // If the declaration is invalid, there is no need to continue with deduction + // or binding, as this can lead to extra error messages. + if (R->isFunctionType() || HasBadDeclarator) D.setInvalidType(); } @@ -988,6 +991,11 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, CurContext->addHiddenDecl(New); } + if (New && New->isInvalidDecl()) { + for (auto *B : Bindings) + B->setInvalidDecl(); + } + if (OpenMP().isInOpenMPDeclareTargetContext()) OpenMP().checkDeclIsAllowedInOpenMPTarget(nullptr, New); diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp index 45329b766bc281..dcccd63ae40ef3 100644 --- a/clang/test/Parser/cxx1z-decomposition.cpp +++ b/clang/test/Parser/cxx1z-decomposition.cpp @@ -121,8 +121,8 @@ namespace BadSpecifiers { // CHECK: :[[@LINE-1]]:13: error: structured binding declaration '[K]' requires an initializer; expected '=' or braced initializer list int [5] arr = {0}; // expected-error {{place the brackets after the name}} - auto *[f] = s; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}} - auto S::*[g] = s; // expected-error {{cannot be declared with type 'auto S::*'}} expected-error {{incompatible initializer}} + auto *[f] = s; // expected-error {{cannot be declared with type 'auto *'}} + auto S::*[g] = s; // expected-error {{cannot be declared with type 'auto S::*'}} // ref-qualifiers are OK. auto &&[ok_1] = S(); diff --git a/clang/test/SemaCXX/GH222605.cpp b/clang/test/SemaCXX/GH222605.cpp new file mode 100644 index 00000000000000..dbe81addf49847 --- /dev/null +++ b/clang/test/SemaCXX/GH222605.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s + +struct S { + int *p; + int *q; +}; + +struct Point { + double x; + double y; + double z; +}; + +void test_original(S s) { + auto* [x, y] = s; // expected-error {{structured binding declaration cannot be declared with type 'auto *'; declared type must be 'auto' or reference to 'auto'}} +} + +void test_other_struct(Point pt) { + auto* [x, y, z] = pt; // expected-error {{structured binding declaration cannot be declared with type 'auto *'; declared type must be 'auto' or reference to 'auto'}} +} + +void test_auto_variations(S s) { + auto*& [a, b] = s; // expected-error {{structured binding declaration cannot be declared with type 'auto *&'; declared type must be 'auto' or reference to 'auto'}} + const auto* [c, d] = s; // expected-error {{structured binding declaration cannot be declared with type 'const auto *'; declared type must be 'auto' or reference to 'auto'}} + const auto*& [e, f] = s; // expected-error {{structured binding declaration cannot be declared with type 'const auto *&'; declared type must be 'auto' or reference to 'auto'}} +} + +void test_valid(S s, Point pt) { + auto [a, b] = s; + auto& [c, d] = s; + const auto& [e, f] = s; + auto&& [g, h] = S{}; + + auto [x, y, z] = pt; + const auto& [cx, cy, cz] = pt; +} + +void test_other_errors(S s) { + auto* p = s; // expected-error {{variable 'p' with type 'auto *' has incompatible initializer of type 'S'}} + + auto [a] = s; // expected-error {{type 'S' binds to 2 elements, but only 1 name was provided}} + auto [b, c, d] = s; // expected-error {{type 'S' binds to 2 elements, but 3 names were provided}} + + int n = 0; + auto [x, y] = n; // expected-error {{cannot bind non-class, non-array type 'int'}} +} + +void test_pointer(S *s) { + auto* [a, b] = s; // expected-error {{structured binding declaration cannot be declared with type 'auto *'; declared type must be 'auto' or reference to 'auto'}} + auto** [c, d] = &s; // expected-error {{structured binding declaration cannot be declared with type 'auto **'; declared type must be 'auto' or reference to 'auto'}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
