[clang] 6408317 - [clang][Sema] Provide source range to several Wunused warnings

Takuya Shimizu via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 16 03:31:00 PDT 2023


Author: Takuya Shimizu
Date: 2023-06-16T19:26:53+09:00
New Revision: 64083172eea26e50c8b22b85697a825be8bda424

URL: https://github.com/llvm/llvm-project/commit/64083172eea26e50c8b22b85697a825be8bda424
DIFF: https://github.com/llvm/llvm-project/commit/64083172eea26e50c8b22b85697a825be8bda424.diff

LOG: [clang][Sema] Provide source range to several Wunused warnings

When the diagnosed function/variable is a template specialization, the source range covers the specialization arguments.
e.g.
```
warning: unused function 'func<int>' [-Wunused-function]
template <> int func<int> () {}
                ^~~~~~~~~
```
This comes in line with the printed text in the warning message. In the above case, `func<int>`

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D152707

Added: 
    clang/test/Misc/Inputs/diag-unused-source-ranges.h
    clang/test/Misc/diag-unused-source-ranges.cpp

Modified: 
    clang/lib/Sema/Sema.cpp
    clang/lib/Sema/SemaDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 09084176cbf41..694e07b46aaf0 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1347,10 +1347,14 @@ void Sema::ActOnEndOfTranslationUnit() {
           DiagD = FD;
         if (DiagD->isDeleted())
           continue; // Deleted functions are supposed to be unused.
+        SourceRange DiagRange = DiagD->getLocation();
+        if (const ASTTemplateArgumentListInfo *ASTTAL =
+                DiagD->getTemplateSpecializationArgsAsWritten())
+          DiagRange.setEnd(ASTTAL->RAngleLoc);
         if (DiagD->isReferenced()) {
           if (isa<CXXMethodDecl>(DiagD))
             Diag(DiagD->getLocation(), diag::warn_unneeded_member_function)
-                << DiagD;
+                << DiagD << DiagRange;
           else {
             if (FD->getStorageClass() == SC_Static &&
                 !FD->isInlineSpecified() &&
@@ -1358,39 +1362,46 @@ void Sema::ActOnEndOfTranslationUnit() {
                    SourceMgr.getExpansionLoc(FD->getLocation())))
               Diag(DiagD->getLocation(),
                    diag::warn_unneeded_static_internal_decl)
-                  << DiagD;
+                  << DiagD << DiagRange;
             else
               Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
-                  << /*function*/ 0 << DiagD;
+                  << /*function*/ 0 << DiagD << DiagRange;
           }
         } else {
           if (FD->getDescribedFunctionTemplate())
             Diag(DiagD->getLocation(), diag::warn_unused_template)
-                << /*function*/ 0 << DiagD;
+                << /*function*/ 0 << DiagD << DiagRange;
           else
             Diag(DiagD->getLocation(), isa<CXXMethodDecl>(DiagD)
                                            ? diag::warn_unused_member_function
                                            : diag::warn_unused_function)
-                << DiagD;
+                << DiagD << DiagRange;
         }
       } else {
         const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
         if (!DiagD)
           DiagD = cast<VarDecl>(*I);
+        SourceRange DiagRange = DiagD->getLocation();
+        if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(DiagD)) {
+          if (const ASTTemplateArgumentListInfo *ASTTAL =
+                  VTSD->getTemplateArgsInfo())
+            DiagRange.setEnd(ASTTAL->RAngleLoc);
+        }
         if (DiagD->isReferenced()) {
           Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
-              << /*variable*/ 1 << DiagD;
+              << /*variable*/ 1 << DiagD << DiagRange;
         } else if (DiagD->getDescribedVarTemplate()) {
           Diag(DiagD->getLocation(), diag::warn_unused_template)
-              << /*variable*/ 1 << DiagD;
+              << /*variable*/ 1 << DiagD << DiagRange;
         } else if (DiagD->getType().isConstQualified()) {
           const SourceManager &SM = SourceMgr;
           if (SM.getMainFileID() != SM.getFileID(DiagD->getLocation()) ||
               !PP.getLangOpts().IsHeaderFile)
             Diag(DiagD->getLocation(), diag::warn_unused_const_variable)
-                << DiagD;
+                << DiagD << DiagRange;
         } else {
-          Diag(DiagD->getLocation(), diag::warn_unused_variable) << DiagD;
+          Diag(DiagD->getLocation(), diag::warn_unused_variable)
+              << DiagD << DiagRange;
         }
       }
     }

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 757c4c310be3d..e93f86821d846 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2151,7 +2151,8 @@ void Sema::DiagnoseUnusedDecl(const NamedDecl *D, DiagReceiverTy DiagReceiver) {
   else
     DiagID = diag::warn_unused_variable;
 
-  DiagReceiver(D->getLocation(), PDiag(DiagID) << D << Hint);
+  SourceLocation DiagLoc = D->getLocation();
+  DiagReceiver(DiagLoc, PDiag(DiagID) << D << Hint << SourceRange(DiagLoc));
 }
 
 void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD,

diff  --git a/clang/test/Misc/Inputs/diag-unused-source-ranges.h b/clang/test/Misc/Inputs/diag-unused-source-ranges.h
new file mode 100644
index 0000000000000..e737732654102
--- /dev/null
+++ b/clang/test/Misc/Inputs/diag-unused-source-ranges.h
@@ -0,0 +1 @@
+static void thing(void) {}

diff  --git a/clang/test/Misc/diag-unused-source-ranges.cpp b/clang/test/Misc/diag-unused-source-ranges.cpp
new file mode 100644
index 0000000000000..6b7fd7d263278
--- /dev/null
+++ b/clang/test/Misc/diag-unused-source-ranges.cpp
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -Wunused -Wunused-template -Wunused-exception-parameter -Wunused-member-function -fdiagnostics-print-source-range-info %s 2>&1 | FileCheck %s --strict-whitespace
+#include "Inputs/diag-unused-source-ranges.h"
+
+#define CAT(a, b) a ## b
+
+// CHECK:      :{55:15-55:20}: warning: unused exception parameter 'param'
+// CHECK-NEXT:   catch (int &param) {}
+// CHECK-NEXT:               ^~~~~{{$}}
+
+// CHECK:      :{53:7-53:12}: warning: unused variable 'local'
+// CHECK-NEXT:   int local = 0;
+// CHECK-NEXT:       ^~~~~{{$}}
+
+// CHECK:      In file included from
+// CHECK-NEXT: :{1:13-1:18}: warning: 'static' function 'thing' declared in header file should be declared 'static inline'
+// CHECK-NEXT:   static void thing(void) {}
+// CHECK-NEXT:               ^~~~~{{$}}
+
+namespace {
+class A {
+  // CHECK:      :{[[@LINE+3]]:10-[[@LINE+3]]:14}: warning: member function 'func' is not needed
+  // CHECK-NEXT:   void func() {}
+  // CHECK-NEXT:        ^~~~{{$}}
+    void func() {}
+  // CHECK:      :{[[@LINE+3]]:32-[[@LINE+3]]:37}: warning: unused function template
+  // CHECK-NEXT:   void templ(T) {}
+  // CHECK-NEXT:        ^~~~~{{$}}
+    template <typename T> void templ(T) {}
+  // CHECK:      :{[[@LINE+3]]:22-[[@LINE+3]]:32}: warning: member function 'templ<int>' is not needed
+  // CHECK-NEXT:   void templ<int>(int) {}
+  // CHECK-NEXT:        ^~~~~~~~~~{{$}}
+    template <> void templ<int>(int) {}
+  // CHECK:      :{[[@LINE+3]]:22-[[@LINE+3]]:27}: warning: member function 'templ<float>' is not needed
+  // CHECK-NEXT:   void templ(float) {}
+  // CHECK-NEXT:        ^~~~~{{$}}
+    template <> void templ(float) {}
+
+  // CHECK:      :{[[@LINE+4]]:10-[[@LINE+4]]:13}: warning: unused function template
+  // CHECK-NEXT:   void foo() {
+  // CHECK-NEXT:        ^~~{{$}}
+    template <typename T>
+    void foo() {
+      func();
+      templ(0);
+      templ(0.0f);
+      templ(0.0);
+    }
+};
+// CHECK:      :{[[@LINE+3]]:12-[[@LINE+3]]:23}: warning: unused function 'unused_func'
+// CHECK-NEXT:   static int unused_func(int aaa, char bbb) {
+// CHECK-NEXT:              ^~~~~~~~~~~{{$}}
+static int unused_func(int aaa, char bbb) {
+  int local = 0;
+  try{}
+  catch (int &param) {}
+  return 0;
+}
+
+// CHECK:      :{[[@LINE+4]]:6-[[@LINE+4]]:16}: warning: unused function template
+// CHECK-NEXT:   auto arrow_decl(T a, T b) ->
+// CHECK-NEXT:        ^~~~~~~~~~{{$}}
+template <typename T>
+auto arrow_decl(T a, T b) -> decltype(a + b) { thing(); return a + b; }
+
+// CHECK:      :{[[@LINE+4]]:6-[[@LINE+4]]:21}: warning: unused function 'arrow_decl<int>'
+// CHECK-NEXT:   auto arrow_decl<int>(int a, int b) ->
+// CHECK-NEXT:        ^~~~~~~~~~~~~~~{{$}}
+template <>
+auto arrow_decl<int>(int a, int b) -> int { return a + b; }
+
+
+// CHECK:      :{[[@LINE+4]]:10-[[@LINE+4]]:20}: warning: unused function template
+// CHECK-NEXT:   static T func_templ(int bbb, T ccc) {
+// CHECK-NEXT:            ^~~~~~~~~~{{$}}
+template <typename T>
+static T func_templ(int bbb, T ccc) {
+  return ccc;
+}
+
+// CHECK:      :{[[@LINE+3]]:17-[[@LINE+3]]:32}: warning: function 'func_templ<int>' is not needed
+// CHECK-NEXT:   int func_templ<int>(int bbb, int ccc) {
+// CHECK-NEXT:       ^~~~~~~~~~~~~~~{{$}}
+template <> int func_templ<int>(int bbb, int ccc) {
+  return bbb;
+}
+
+// CHECK:      :{[[@LINE+3]]:35-[[@LINE+3]]:47}: warning: unused function template
+// CHECK-NEXT:   static void never_called() {
+// CHECK-NEXT:               ^~~~~~~~~~~~{{$}}
+template <typename T> static void never_called() {
+  func_templ<int>(0, 0);
+}
+
+// CHECK:      :{[[@LINE+3]]:22-[[@LINE+3]]:31}: warning: unused variable template
+// CHECK-NEXT:   int var_templ =
+// CHECK-NEXT:       ^~~~~~~~~{{$}}
+template <int n> int var_templ = n * var_templ<n-1>;
+// CHECK:      :{[[@LINE+3]]:17-[[@LINE+3]]:29}: warning: variable 'var_templ<0>' is not needed
+// CHECK-NEXT:   int var_templ<0> =
+// CHECK-NEXT:       ^~~~~~~~~~~~{{$}}
+template <> int var_templ<0> = 1;
+struct {
+// CHECK:      :{[[@LINE+3]]:8-[[@LINE+3]]:11}: warning: unused member function 'fun'
+// CHECK-NEXT:   void fun() {}
+// CHECK-NEXT:        ^~~{{$}}
+  void fun() {}
+// CHECK:      :{[[@LINE+3]]:3-[[@LINE+3]]:8}: warning: unused variable 'var_x'
+// CHECK-NEXT:   } var_x;
+// CHECK-NEXT:     ^~~~~{{$}}
+} var_x;
+
+// CHECK:      :{[[@LINE+5]]:12-[[@LINE+6]]:12}: warning: unused variable 'new_line'
+// CHECK-NEXT:   static int CAT(new_,
+// CHECK-NEXT:              ^~~~~~~~~{{$}}
+// CHECK-NEXT:         line) =
+// CHECK-NEXT:         ~~~~~{{$}}
+static int CAT(new_,
+      line) = sizeof(var_templ<0>);
+}
+
+// CHECK:      :{[[@LINE+3]]:15-[[@LINE+3]]:27}: warning: unused variable 'const_unused'
+// CHECK-NEXT:   constexpr int const_unused = 1
+// CHECK-NEXT:                 ^~~~~~~~~~~~{{$}}
+constexpr int const_unused = 1;


        


More information about the cfe-commits mailing list