[Clang] emit -Wunused-variable warning for unused structured bindings without the [[maybe_unused]] attribute (#127061)

Fixes #125810 

---

This patch resolves an issue in Clang where the `-Wunused-variable`
warning was suppressed for structured bindings with elements marked
`[[maybe_unused]]`, causing the entire declaration to be treated as used
and preventing the warning from being emitted.
This commit is contained in:
Oleksandr T. 2025-03-19 23:06:10 +02:00 committed by GitHub
parent a306ae0eca
commit 01d28c1cd7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 5 deletions

View File

@ -348,6 +348,8 @@ Bug Fixes to C++ Support
- Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411)
- Clang was previously coalescing volatile writes to members of volatile base class subobjects.
The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824)
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1934,13 +1934,14 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
// For a decomposition declaration, warn if none of the bindings are
// referenced, instead of if the variable itself is referenced (which
// it is, by the bindings' expressions).
bool IsAllPlaceholders = true;
bool IsAllIgnored = true;
for (const auto *BD : DD->bindings()) {
if (BD->isReferenced() || BD->hasAttr<UnusedAttr>())
if (BD->isReferenced())
return false;
IsAllPlaceholders = IsAllPlaceholders && BD->isPlaceholderVar(LangOpts);
IsAllIgnored = IsAllIgnored && (BD->isPlaceholderVar(LangOpts) ||
BD->hasAttr<UnusedAttr>());
}
if (IsAllPlaceholders)
if (IsAllIgnored)
return false;
} else if (!D->getDeclName()) {
return false;

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 -Wunused %s
namespace GH125810 {
struct S {
int a, b;
};
void t(S s) {
auto &[_, _] = s;
auto &[a1, _] = s; // expected-warning {{unused variable '[a1, _]'}}
auto &[_, b2] = s; // expected-warning {{unused variable '[_, b2]'}}
auto &[a3 [[maybe_unused]], b3 [[maybe_unused]]] = s;
auto &[a4, b4 [[maybe_unused]]] = s; // expected-warning {{unused variable '[a4, b4]'}}
auto &[a5 [[maybe_unused]], b5] = s; // expected-warning {{unused variable '[a5, b5]'}}
}
}

View File

@ -114,7 +114,8 @@ namespace maybe_unused_binding {
void test() {
struct X { int a, b; } x;
auto [a [[maybe_unused]], b] = x; // expected-warning {{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}
auto [a [[maybe_unused]], b] = x; // expected-warning {{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}} \
// expected-warning {{unused variable '[a, b]'}}
}
}