[clang] Add -Wunused-but-set-global (#188291)
Commit fd11cf430e5a extended `-Wunused-but-set-variable` to static
globals. To make it easier for downstream projects to integrate this new
functionality, this commit introduces `-Wunused-but-set-global` so it
can be easily disabled as projects investigate and fix new findings.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0dbe667..03fffc4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -231,7 +231,10 @@
Improvements to Clang's diagnostics
-----------------------------------
- ``-Wunused-but-set-variable`` now diagnoses file-scope variables with
- internal linkage (``static`` storage class) that are assigned but never used. (#GH148361)
+ internal linkage (``static`` storage class) that are assigned but never used.
+ This new coverage is added under the subgroup ``-Wunused-but-set-global``,
+ allowing it to be disabled independently with ``-Wno-unused-but-set-global``.
+ (#GH148361)
- Added ``-Wlifetime-safety`` to enable lifetime safety analysis,
a CFG-based intra-procedural analysis that detects use-after-free and related
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index e440c9d..a8d9745 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1158,7 +1158,9 @@
def UnusedConstVariable : DiagGroup<"unused-const-variable">;
def UnusedVariable : DiagGroup<"unused-variable",
[UnusedConstVariable]>;
-def UnusedButSetVariable : DiagGroup<"unused-but-set-variable">;
+def UnusedButSetGlobal : DiagGroup<"unused-but-set-global">;
+def UnusedButSetVariable
+ : DiagGroup<"unused-but-set-variable", [UnusedButSetGlobal]>;
def UnusedLocalTypedef : DiagGroup<"unused-local-typedef">;
def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
def UnusedGetterReturnValue : DiagGroup<"unused-getter-return-value">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e766d6e..63f2412 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -433,6 +433,9 @@
InGroup<UnusedVariable>, DefaultIgnore;
def warn_unused_but_set_variable : Warning<"variable %0 set but not used">,
InGroup<UnusedButSetVariable>, DefaultIgnore;
+def warn_unused_but_set_global : Warning<"variable %0 set but not used">,
+ InGroup<UnusedButSetGlobal>,
+ DefaultIgnore;
def warn_unused_local_typedef : Warning<
"unused %select{typedef|type alias}0 %1">,
InGroup<UnusedLocalTypedef>, DefaultIgnore;
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 620b135..98318fc 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1610,7 +1610,7 @@
emitAndClearUnusedLocalTypedefWarnings();
}
- if (!Diags.isIgnored(diag::warn_unused_but_set_variable, SourceLocation())) {
+ if (!Diags.isIgnored(diag::warn_unused_but_set_global, SourceLocation())) {
// Diagnose unused-but-set static globals in a deterministic order.
// Not tracking shadowing info for static globals; there's nothing to
// shadow.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c862c09..5d204c4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2245,8 +2245,13 @@
return;
}
- unsigned DiagID = isa<ParmVarDecl>(VD) ? diag::warn_unused_but_set_parameter
- : diag::warn_unused_but_set_variable;
+ unsigned DiagID;
+ if (isa<ParmVarDecl>(VD))
+ DiagID = diag::warn_unused_but_set_parameter;
+ else if (VD->isFileVarDecl())
+ DiagID = diag::warn_unused_but_set_global;
+ else
+ DiagID = diag::warn_unused_but_set_variable;
DiagReceiver(VD->getLocation(), PDiag(DiagID) << VD);
}
diff --git a/clang/test/C/C2y/n3622.c b/clang/test/C/C2y/n3622.c
index d90b0c5..afcd831 100644
--- a/clang/test/C/C2y/n3622.c
+++ b/clang/test/C/C2y/n3622.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -verify=good -pedantic -Wall -Wno-unused-but-set-variable -std=c2y %s
-// RUN: %clang_cc1 -verify=compat,expected -pedantic -Wall -Wno-unused-but-set-variable -Wpre-c2y-compat -std=c2y %s
-// RUN: %clang_cc1 -verify=ped,expected -pedantic -Wall -Wno-unused-but-set-variable -std=c23 %s
-// RUN: %clang_cc1 -verify=ped,expected -pedantic -Wall -Wno-unused-but-set-variable -std=c17 %s
+// RUN: %clang_cc1 -verify=good -pedantic -Wall -Wno-unused-but-set-global -std=c2y %s
+// RUN: %clang_cc1 -verify=compat,expected -pedantic -Wall -Wno-unused-but-set-global -Wpre-c2y-compat -std=c2y %s
+// RUN: %clang_cc1 -verify=ped,expected -pedantic -Wall -Wno-unused-but-set-global -std=c23 %s
+// RUN: %clang_cc1 -verify=ped,expected -pedantic -Wall -Wno-unused-but-set-global -std=c17 %s
// good-no-diagnostics
/* WG14 N3622: Clang 22
diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c
index 83b8d4d..6d6c4e5 100644
--- a/clang/test/Misc/warning-wall.c
+++ b/clang/test/Misc/warning-wall.c
@@ -84,6 +84,7 @@
CHECK-NEXT: -Wunused-variable
CHECK-NEXT: -Wunused-const-variable
CHECK-NEXT: -Wunused-but-set-variable
+CHECK-NEXT: -Wunused-but-set-global
CHECK-NEXT: -Wunused-property-ivar
CHECK-NEXT: -Wvolatile-register-var
CHECK-NEXT: -Wobjc-missing-super-calls
diff --git a/clang/test/Sema/warn-unused-but-set-static-global.c b/clang/test/Sema/warn-unused-but-set-static-global.c
index 7c4d20a..e6abcad 100644
--- a/clang/test/Sema/warn-unused-but-set-static-global.c
+++ b/clang/test/Sema/warn-unused-but-set-static-global.c
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-but-set-variable -I %S/Inputs -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-but-set-variable -Wno-unused-but-set-global -I %S/Inputs -verify=no-global %s
+// no-global-no-diagnostics
// Test that header-defined static globals don't warn.
#include "warn-unused-but-set-static-global-header.h"
diff --git a/clang/test/Sema/warn-unused-but-set-static-global.cpp b/clang/test/Sema/warn-unused-but-set-static-global.cpp
index 1ddd7eb..e035484 100644
--- a/clang/test/Sema/warn-unused-but-set-static-global.cpp
+++ b/clang/test/Sema/warn-unused-but-set-static-global.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-but-set-variable -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-but-set-variable -Wno-unused-but-set-global -verify=no-global -std=c++17 %s
+// no-global-no-diagnostics
static thread_local int tl_set_unused; // expected-warning {{variable 'tl_set_unused' set but not used}}
static thread_local int tl_set_and_used;