[clang-tools-extra] r265384 - [clang-tidy] Add a check to detect static definitions in anonymous namespace.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 5 04:42:18 PDT 2016


Author: hokein
Date: Tue Apr  5 06:42:08 2016
New Revision: 265384

URL: http://llvm.org/viewvc/llvm-project?rev=265384&view=rev
Log:
[clang-tidy] Add a check to detect static definitions in anonymous namespace.

Summary: Fixes PR26595

Reviewers: alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D18180

Added:
    clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
    clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/readability-static-definition-in-anonymous-namespace.rst
    clang-tools-extra/trunk/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt?rev=265384&r1=265383&r2=265384&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt Tue Apr  5 06:42:08 2016
@@ -17,6 +17,7 @@ add_clang_library(clangTidyReadabilityMo
   RedundantSmartptrGetCheck.cpp
   RedundantStringInitCheck.cpp
   SimplifyBooleanExprCheck.cpp
+  StaticDefinitionInAnonymousNamespaceCheck.cpp
   UniqueptrDeleteReleaseCheck.cpp
 
   LINK_LIBS

Modified: clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp?rev=265384&r1=265383&r2=265384&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp Tue Apr  5 06:42:08 2016
@@ -24,6 +24,7 @@
 #include "RedundantStringCStrCheck.h"
 #include "RedundantStringInitCheck.h"
 #include "SimplifyBooleanExprCheck.h"
+#include "StaticDefinitionInAnonymousNamespaceCheck.h"
 #include "UniqueptrDeleteReleaseCheck.h"
 
 namespace clang {
@@ -49,6 +50,8 @@ public:
         "readability-implicit-bool-cast");
     CheckFactories.registerCheck<InconsistentDeclarationParameterNameCheck>(
         "readability-inconsistent-declaration-parameter-name");
+    CheckFactories.registerCheck<StaticDefinitionInAnonymousNamespaceCheck>(
+        "readability-static-definition-in-anonymous-namespace");
     CheckFactories.registerCheck<readability::NamedParameterCheck>(
         "readability-named-parameter");
     CheckFactories.registerCheck<RedundantControlFlowCheck>(

Added: clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp?rev=265384&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp Tue Apr  5 06:42:08 2016
@@ -0,0 +1,72 @@
+//===--- StaticDefinitionInAnonymousNamespaceCheck.cpp - clang-tidy--------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StaticDefinitionInAnonymousNamespaceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+namespace {
+AST_POLYMORPHIC_MATCHER(isStatic, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+                                                                  VarDecl)) {
+  return Node.getStorageClass() == SC_Static;
+}
+} // namespace
+
+void StaticDefinitionInAnonymousNamespaceCheck::registerMatchers(
+    MatchFinder *Finder) {
+  Finder->addMatcher(namedDecl(anyOf(functionDecl(isDefinition(), isStatic()),
+                                     varDecl(isDefinition(), isStatic())),
+                               hasParent(namespaceDecl(isAnonymous())))
+                         .bind("static-def"),
+                     this);
+}
+
+void StaticDefinitionInAnonymousNamespaceCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *Def = Result.Nodes.getNodeAs<NamedDecl>("static-def");
+  // Skips all static definitions defined in Macro.
+  if (Def->getLocation().isMacroID())
+    return;
+
+  // Skips all static definitions in function scope.
+  const DeclContext *DC = Def->getDeclContext();
+  if (DC->getDeclKind() != Decl::Namespace)
+    return;
+
+  auto Diag =
+      diag(Def->getLocation(), "%0 is a static definition in "
+                               "anonymous namespace; static is redundant here")
+      << Def;
+  Token Tok;
+  SourceLocation Loc = Def->getSourceRange().getBegin();
+  while (Loc < Def->getSourceRange().getEnd() &&
+         !Lexer::getRawToken(Loc, Tok, *Result.SourceManager,
+                             Result.Context->getLangOpts(), true)) {
+    SourceRange TokenRange(Tok.getLocation(), Tok.getEndLoc());
+    StringRef SourceText = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(TokenRange),
+        *Result.SourceManager, Result.Context->getLangOpts());
+    if (SourceText == "static") {
+      Diag << FixItHint::CreateRemoval(TokenRange);
+      break;
+    }
+    Loc = Tok.getEndLoc();
+  }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h?rev=265384&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h Tue Apr  5 06:42:08 2016
@@ -0,0 +1,35 @@
+//===--- StaticDefinitionInAnonymousNamespaceCheck.h - clang-tidy*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_DEFINITION_IN_ANONYMOUS_NAMESPACE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_DEFINITION_IN_ANONYMOUS_NAMESPACE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Finds static function and variable definitions in anonymous namespace.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-static-definition-in-anonymous-namespace.html
+class StaticDefinitionInAnonymousNamespaceCheck : public ClangTidyCheck {
+public:
+  StaticDefinitionInAnonymousNamespaceCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_DEFINITION_IN_ANONYMOUS_NAMESPACE_H

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=265384&r1=265383&r2=265384&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Tue Apr  5 06:42:08 2016
@@ -107,4 +107,5 @@ Clang-Tidy Checks
    readability-redundant-string-cstr
    readability-redundant-string-init
    readability-simplify-boolean-expr
+   readability-static-definition-in-anonymous-namespace
    readability-uniqueptr-delete-release

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/readability-static-definition-in-anonymous-namespace.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/readability-static-definition-in-anonymous-namespace.rst?rev=265384&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/readability-static-definition-in-anonymous-namespace.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/readability-static-definition-in-anonymous-namespace.rst Tue Apr  5 06:42:08 2016
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - readability-static-definition-in-anonymous-namespace
+
+readability-static-definition-in-anonymous-namespace
+====================================================
+
+Finds static function and variable definitions in anonymous namespace.
+
+In this case, ``static`` is redundant, because anonymous namespace limits the
+visibility of definitions to a single translation unit.
+
+.. code:: c++
+  namespace {
+    static int a = 1; // Warning.
+    static const b = 1; // Warning.
+  }
+
+The check will apply a fix by removing the redundant ``static`` qualifier.

Added: clang-tools-extra/trunk/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp?rev=265384&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-static-definition-in-anonymous-namespace.cpp Tue Apr  5 06:42:08 2016
@@ -0,0 +1,49 @@
+// RUN: %check_clang_tidy %s readability-static-definition-in-anonymous-namespace %t
+
+namespace {
+
+int a = 1;
+const int b = 1;
+static int c = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'c' is a static definition in anonymous namespace; static is redundant here [readability-static-definition-in-anonymous-namespace]
+// CHECK-FIXES: {{^}}int c = 1;
+static const int d = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'd' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}const int d = 1;
+const static int e = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'e' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}const int e = 1;
+
+void f() {
+  int a = 1;
+  static int b = 1;
+}
+
+static int g() {
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'g' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}int g() {
+  return 1;
+}
+
+#define DEFINE_STATIC static
+// CHECK-FIXES: {{^}}#define DEFINE_STATIC static
+DEFINE_STATIC int h = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 'h' is a static definition in anonymous namespace
+// CHECK-FIXES: {{^}}DEFINE_STATIC int h = 1;
+
+#define DEFINE_STATIC_VAR(x) static int x = 2
+// CHECK-FIXES: {{^}}#define DEFINE_STATIC_VAR(x) static int x = 2
+DEFINE_STATIC_VAR(i);
+// CHECK-FIXES: {{^}}DEFINE_STATIC_VAR(i);
+
+} // namespace
+
+namespace N {
+
+int a = 1;
+const int b = 1;
+static int c = 1;
+static const int d = 1;
+const static int e = 1;
+
+} // namespace N




More information about the cfe-commits mailing list