Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ Bug Fixes to C++ Support
- Fixed an assertion failure affecting code that uses C++23 "deducing this". (#GH130272)
- Clang now properly instantiates destructors for initialized members within non-delegating constructors. (#GH93251)
- Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411)
- 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
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions clang/test/SemaCXX/unused-bindings.cpp
Original file line number Diff line number Diff line change
@@ -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]'}}
}
}
3 changes: 2 additions & 1 deletion clang/test/SemaCXX/unused.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]'}}
}

}
Expand Down