khuttun created this revision.
khuttun added a reviewer: alexfh.
Herald added subscribers: xazax.hun, mgorny.

Warns on std::map and std::unordered_map lookups done with operator[]. 
Inserting values with operator[] is still allowed.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D46317

Files:
  clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tidy/bugprone/CMakeLists.txt
  clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.cpp
  clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/bugprone-map-subscript-operator-lookup.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/bugprone-map-subscript-operator-lookup.cpp

Index: test/clang-tidy/bugprone-map-subscript-operator-lookup.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/bugprone-map-subscript-operator-lookup.cpp
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s bugprone-map-subscript-operator-lookup %t
+
+namespace std {
+
+template <typename T>
+struct allocator {};
+
+template <typename T>
+struct equal_to {};
+
+template <typename T>
+struct hash {};
+
+template <typename T>
+struct less {};
+
+template <typename T, typename U>
+struct pair {};
+
+template <typename Key,
+          typename T,
+          typename Compare = std::less<Key>,
+          typename Allocator = std::allocator<std::pair<const Key, T>>>
+struct map {
+  T &operator[](const Key &);
+  T &operator[](Key &&);
+};
+
+// the check should be able to match std lib calls even if the functions are
+// declared inside inline namespaces
+inline namespace v1 {
+
+template <typename Key,
+          typename T,
+          typename Hash = std::hash<Key>,
+          typename KeyEqual = std::equal_to<Key>,
+          typename Allocator = std::allocator<std::pair<const Key, T>>>
+struct unordered_map {
+  T &operator[](const Key &);
+  T &operator[](Key &&);
+};
+
+} // namespace v1
+} // namespace std
+
+struct Foo {
+  int getter() const;
+  void setter(int);
+};
+
+void warning() {
+  std::map<int, Foo> Map;
+  auto Foo1 = Map[42];
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+
+  std::unordered_map<int, Foo> UMap;
+  auto Foo2 = UMap[42];
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void noWarning() {
+  std::map<int, Foo> MapOk;
+  MapOk[42] = Foo{};
+
+  std::unordered_map<int, Foo> UMapOk;
+  UMapOk[42] = Foo{};
+}
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -33,6 +33,7 @@
    bugprone-lambda-function-name
    bugprone-macro-parentheses
    bugprone-macro-repeated-side-effects
+   bugprone-map-subscript-operator-lookup
    bugprone-misplaced-operator-in-strlen-in-alloc
    bugprone-misplaced-widening-cast
    bugprone-move-forwarding-reference
@@ -91,8 +92,8 @@
    cppcoreguidelines-pro-type-vararg
    cppcoreguidelines-slicing
    cppcoreguidelines-special-member-functions
-   fuchsia-header-anon-namespaces (redirects to google-build-namespaces) <fuchsia-header-anon-namespaces>
    fuchsia-default-arguments
+   fuchsia-header-anon-namespaces (redirects to google-build-namespaces) <fuchsia-header-anon-namespaces>
    fuchsia-multiple-inheritance
    fuchsia-overloaded-operator
    fuchsia-statically-constructed-objects
Index: docs/clang-tidy/checks/bugprone-map-subscript-operator-lookup.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/bugprone-map-subscript-operator-lookup.rst
@@ -0,0 +1,6 @@
+.. title:: clang-tidy - bugprone-map-subscript-operator-lookup
+
+bugprone-map-subscript-operator-lookup
+======================================
+
+FIXME: Describe what patterns does the check detect and why. Give examples.
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,11 @@
 Improvements to clang-tidy
 --------------------------
 
+- New :doc:`bugprone-map-subscript-operator-lookup
+  <clang-tidy/checks/bugprone-map-subscript-operator-lookup>` check
+
+  FIXME: add release notes.
+
 - New module `abseil` for checks related to the `Abseil <https://abseil.io>`_
   library.
 
Index: clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.h
@@ -0,0 +1,35 @@
+//===--- MapSubscriptOperatorLookupCheck.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_BUGPRONE_MAPSUBSCRIPTOPERATORLOOKUPCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MAPSUBSCRIPTOPERATORLOOKUPCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-map-subscript-operator-lookup.html
+class MapSubscriptOperatorLookupCheck : public ClangTidyCheck {
+public:
+  MapSubscriptOperatorLookupCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MAPSUBSCRIPTOPERATORLOOKUPCHECK_H
Index: clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.cpp
@@ -0,0 +1,45 @@
+//===--- MapSubscriptOperatorLookupCheck.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 "MapSubscriptOperatorLookupCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+void MapSubscriptOperatorLookupCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      cxxOperatorCallExpr(
+          callee(cxxMethodDecl(
+              hasName("operator[]"),
+              ofClass(hasAnyName("::std::map", "::std::unordered_map")))),
+          hasParent(implicitCastExpr(
+              anyOf(hasImplicitDestinationType(isConstQualified()),
+                    hasCastKind(CK_LValueToRValue)))))
+          .bind("match"),
+      this);
+}
+
+void MapSubscriptOperatorLookupCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  if (const auto *Matched = Result.Nodes.getNodeAs<CallExpr>("match")) {
+    diag(Matched->getLocStart(), "do not use operator[] for map lookup")
+        << Matched->getSourceRange();
+    diag(Matched->getLocStart(), "consider using find() instead",
+         DiagnosticIDs::Note);
+  }
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- clang-tidy/bugprone/CMakeLists.txt
+++ clang-tidy/bugprone/CMakeLists.txt
@@ -16,6 +16,7 @@
   LambdaFunctionNameCheck.cpp
   MacroParenthesesCheck.cpp
   MacroRepeatedSideEffectsCheck.cpp
+  MapSubscriptOperatorLookupCheck.cpp
   MisplacedOperatorInStrlenInAllocCheck.cpp
   MisplacedWideningCastCheck.cpp
   MoveForwardingReferenceCheck.cpp
Index: clang-tidy/bugprone/BugproneTidyModule.cpp
===================================================================
--- clang-tidy/bugprone/BugproneTidyModule.cpp
+++ clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -24,6 +24,7 @@
 #include "LambdaFunctionNameCheck.h"
 #include "MacroParenthesesCheck.h"
 #include "MacroRepeatedSideEffectsCheck.h"
+#include "MapSubscriptOperatorLookupCheck.h"
 #include "MisplacedOperatorInStrlenInAllocCheck.h"
 #include "MisplacedWideningCastCheck.h"
 #include "MoveForwardingReferenceCheck.h"
@@ -83,6 +84,8 @@
         "bugprone-macro-parentheses");
     CheckFactories.registerCheck<MacroRepeatedSideEffectsCheck>(
         "bugprone-macro-repeated-side-effects");
+    CheckFactories.registerCheck<MapSubscriptOperatorLookupCheck>(
+        "bugprone-map-subscript-operator-lookup");
     CheckFactories.registerCheck<MisplacedOperatorInStrlenInAllocCheck>(
         "bugprone-misplaced-operator-in-strlen-in-alloc");
     CheckFactories.registerCheck<MisplacedWideningCastCheck>(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to