Skip to content

Conversation

@a-tarasyuk
Copy link
Member

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.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 13, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 13, 2025

@llvm/pr-subscribers-clang

Author: Oleksandr T. (a-tarasyuk)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/127061.diff

4 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+5-4)
  • (added) clang/test/SemaCXX/unused-bindings.cpp (+17)
  • (modified) clang/test/SemaCXX/unused.cpp (+2-1)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6344c4b36e357..4f20415ec006d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -160,6 +160,8 @@ Bug Fixes to C++ Support
 - Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
 - The initialization kind of elements of structured bindings
   direct-list-initialized from an array is corrected to direct-initialization.
+- 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
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6eedc77ed20a0..19a73a66be5af 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1921,13 +1921,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;
diff --git a/clang/test/SemaCXX/unused-bindings.cpp b/clang/test/SemaCXX/unused-bindings.cpp
new file mode 100644
index 0000000000000..01f2126133a20
--- /dev/null
+++ b/clang/test/SemaCXX/unused-bindings.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2c -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]'}}
+}
+}
diff --git a/clang/test/SemaCXX/unused.cpp b/clang/test/SemaCXX/unused.cpp
index 1f40c1b1ca903..ab728069f2faf 100644
--- a/clang/test/SemaCXX/unused.cpp
+++ b/clang/test/SemaCXX/unused.cpp
@@ -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]'}}
 }
 
 }

@a-tarasyuk a-tarasyuk requested a review from Fznamznon February 14, 2025 11:44
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@a-tarasyuk a-tarasyuk merged commit 01d28c1 into llvm:main Mar 19, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Clang] -Wunused-variable false negative when not all structured bindings are marked maybe_unused

4 participants