[clang] 29dc47a - [clang][Sema] `-Wshadow` warns about shadowings by static local variables

Takuya Shimizu via cfe-commits cfe-commits at lists.llvm.org
Wed May 24 05:40:18 PDT 2023


Author: Takuya Shimizu
Date: 2023-05-24T21:31:25+09:00
New Revision: 29dc47a9eeeb2e080170109e3e2fb3cd5aad58d2

URL: https://github.com/llvm/llvm-project/commit/29dc47a9eeeb2e080170109e3e2fb3cd5aad58d2
DIFF: https://github.com/llvm/llvm-project/commit/29dc47a9eeeb2e080170109e3e2fb3cd5aad58d2.diff

LOG: [clang][Sema] `-Wshadow` warns about shadowings by static local variables

This patch makes `-Wshadow` warn about the shadowings by static local variables.

Fixes https://github.com/llvm/llvm-project/issues/62850
Differential Revision: https://reviews.llvm.org/D151214

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaDecl.cpp
    clang/test/Sema/warn-shadow.c
    clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
    clang/test/SemaCXX/warn-shadow.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0c369a7f45057..92fe909e5e8a6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -299,6 +299,8 @@ Improvements to Clang's diagnostics
 - Clang constexpr evaluator now prints subobject's name instead of its type in notes
   when a constexpr variable has uninitialized subobjects after its constructor call.
   (`#58601 <https://github.com/llvm/llvm-project/issues/58601>`_)
+- Clang's `-Wshadow` warning now warns about shadowings by static local variables
+  (`#62850: <https://github.com/llvm/llvm-project/issues/62850>`_).
 
 Bug Fixes in This Version
 -------------------------

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 859224780befa..aac57196012aa 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8150,7 +8150,7 @@ NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
     return nullptr;
 
   // Don't diagnose declarations at file scope.
-  if (D->hasGlobalStorage())
+  if (D->hasGlobalStorage() && !D->isStaticLocal())
     return nullptr;
 
   NamedDecl *ShadowedDecl = R.getFoundDecl();

diff  --git a/clang/test/Sema/warn-shadow.c b/clang/test/Sema/warn-shadow.c
index b4b0620395cf7..212ca8803b6fb 100644
--- a/clang/test/Sema/warn-shadow.c
+++ b/clang/test/Sema/warn-shadow.c
@@ -1,18 +1,24 @@
 // RUN: %clang_cc1 -verify -fsyntax-only -fblocks -Wshadow %s
 
-int i;          // expected-note 3 {{previous declaration is here}}
+int i;          // expected-note 4 {{previous declaration is here}}
+static int s;   // expected-note 2 {{previous declaration is here}}
 
 void foo(void) {
   int pass1;
   int i;        // expected-warning {{declaration shadows a variable in the global scope}} \
                 // expected-note {{previous declaration is here}}
+  int s;        // expected-warning {{declaration shadows a variable in the global scope}} \
+                // expected-note {{previous declaration is here}}
   {
     int pass2;
     int i;      // expected-warning {{declaration shadows a local variable}} \
                 // expected-note {{previous declaration is here}}
+    int s;      // expected-warning {{declaration shadows a local variable}} \
+                // expected-note {{previous declaration is here}}
     {
       int pass3;
       int i;    // expected-warning {{declaration shadows a local variable}}
+      int s;    // expected-warning {{declaration shadows a local variable}}
     }
   }
 
@@ -71,3 +77,25 @@ struct PR24718_4 {
     PR24718_3 // Does not shadow a type.
   };
 };
+
+void static_locals() {
+  static int i; // expected-warning {{declaration shadows a variable in the global scope}}
+                // expected-note at -1 {{previous definition is here}}
+                // expected-note at -2 {{previous declaration is here}}
+  int i;        // expected-error {{non-static declaration of 'i' follows static declaration}}
+  static int foo; // expected-note {{previous declaration is here}}
+  static int hoge; // expected-note {{previous declaration is here}}
+  int s; // expected-warning {{declaration shadows a variable in the global scope}}
+  {
+    static int foo; // expected-warning {{declaration shadows a local variable}}
+                    // expected-note at -1 {{previous declaration is here}}
+    static int i; // expected-warning {{declaration shadows a local variable}}
+                  // expected-note at -1 {{previous declaration is here}}
+    int hoge; // expected-warning {{declaration shadows a local variable}}
+    {
+      static int foo; // expected-warning {{declaration shadows a local variable}}
+      int i; // expected-warning {{declaration shadows a local variable}}
+      extern int hoge;
+    }
+  }
+}

diff  --git a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
index e5d4c69dcee06..bda6a65c02168 100644
--- a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -14,11 +14,15 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}}
     auto f2 = [&] { int var = 2; };  // no warning
     auto f3 = [=] (int param) { ; }; // no warning
     auto f4 = [&] (int param) { ; }; // no warning
+    auto f5 = [=] { static int var = 1; };  // no warning
+    auto f6 = [&] { static int var = 2; };  // no warning
 #else
     auto f1 = [=] { int var = 1; };  // expected-warning {{declaration shadows a local variable}}
     auto f2 = [&] { int var = 2; };  // expected-warning {{declaration shadows a local variable}}
     auto f3 = [=] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
     auto f4 = [&] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+    auto f5 = [=] { static int var = 1; };  // expected-warning {{declaration shadows a local variable}}
+    auto f6 = [&] { static int var = 2; };  // expected-warning {{declaration shadows a local variable}}
 #endif
   }
 
@@ -67,11 +71,15 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}}
     auto f2 = [] (int param) { ; }; // no warning
     auto f3 = [param] () { int var = 1; }; // no warning
     auto f4 = [var] (int param) { ; }; // no warning
+    auto f5 = [param] () { static int var = 1; }; // no warning
+    auto f6 = [] { static int var = 1; }; // no warning
 #else
     auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
     auto f2 = [] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
     auto f3 = [param] () { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
     auto f4 = [var] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+    auto f5 = [param] () { static int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+    auto f6 = [] { static int var = 1; }; // expected-warning {{declaration shadows a local variable}}
 #endif
   };
 
@@ -127,6 +135,11 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}}
       int param = 0; // expected-warning {{declaration shadows a local variable}}
     };
   };
+  auto l7 = [&] {
+    auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}}
+      static int param = 0; // expected-warning {{declaration shadows a local variable}}
+    };
+  };
 
   // Generic lambda arguments should work.
 #ifdef AVOID

diff  --git a/clang/test/SemaCXX/warn-shadow.cpp b/clang/test/SemaCXX/warn-shadow.cpp
index 4e1a3c393a9db..de0db219cb9b7 100644
--- a/clang/test/SemaCXX/warn-shadow.cpp
+++ b/clang/test/SemaCXX/warn-shadow.cpp
@@ -2,6 +2,7 @@
 
 namespace {
   int i; // expected-note {{previous declaration is here}}
+  static int s; // expected-note {{previous declaration is here}}
 }
 
 namespace one {
@@ -31,6 +32,7 @@ using namespace yy;
 void foo() {
   int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
+  static int s; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int m;
   int mm;
   int mmm;
@@ -40,7 +42,7 @@ class A {
   static int data; // expected-note 1 {{previous declaration}}
   // expected-note at +1 1 {{previous declaration}}
   int field;
-  int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}}
+  int f1, f2, f3, f4; // expected-note 9 {{previous declaration is here}}
 
   typedef int a1; // expected-note 2 {{previous declaration}}
   using a2=int; // expected-note 2 {{previous declaration}}
@@ -66,6 +68,7 @@ class A {
     char *a2; // no warning
     char *jj; // no warning
     char *jjj; // no warning
+    static char *f1; // expected-warning {{declaration shadows a field of 'A'}}
   }
 
   void test2() {
@@ -305,4 +308,4 @@ void test4() {
   }
 }
 
-}; // namespace structured_binding_tests
\ No newline at end of file
+}; // namespace structured_binding_tests


        


More information about the cfe-commits mailing list