khuttun updated this revision to Diff 261141.
khuttun added a comment.

Fixed @Eugene.Zelenko's comments


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D46317/new/

https://reviews.llvm.org/D46317

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

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-map-subscript-operator-lookup.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-map-subscript-operator-lookup.cpp
@@ -0,0 +1,267 @@
+// 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);
+  bool operator==(const Foo &) const;
+};
+
+using FooPtr = Foo *;
+
+void readInt(const int &);
+void writeInt(int &);
+void copyInt(int);
+
+void readFoo(const Foo &);
+void writeFoo(Foo &);
+void copyFoo(Foo);
+
+void copyFooPtr(Foo *);
+void copyConstFooPtr(const Foo *);
+
+std::map<int, int> IntMap;
+std::map<int, Foo> FooMap;
+std::unordered_map<int, FooPtr> FooPtrMap;
+
+void copyFromMap() {
+  int A = IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  Foo B = FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  FooPtr C = FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void constRefFromMap() {
+  const int &A = IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  const Foo &B = FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  const FooPtr &C = FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:21: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void constPtrFromMap() {
+  const int *A = &IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  const Foo *B = &FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  const FooPtr *C = &FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+int returnInt() {
+  return IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+Foo returnFoo() {
+  return FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+FooPtr returnFooPtr() {
+  return FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+const int &returnRefToConstInt() {
+  return IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+const Foo &returnRefToConstFoo() {
+  return FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+const FooPtr &returnRefToConstFooPtr() {
+  return FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+const int *returnPtrToConstInt() {
+  return &IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+const Foo *returnPtrToConstFoo() {
+  return &FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+const FooPtr *returnPtrToConstFooPtr() {
+  return &FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void callReadX() {
+  readInt(IntMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  readFoo(FooMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void callCopyX() {
+  copyInt(IntMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  copyFoo(FooMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  copyFooPtr(FooPtrMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+  copyConstFooPtr(FooPtrMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void passAddrToFunctionTakingConstPtr() {
+  copyConstFooPtr(&FooMap[1]);
+  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void callConstMemf() {
+  FooMap[1].getter();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void deref() {
+  Foo F = *FooPtrMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+  FooPtrMap[1]->getter();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+  FooPtrMap[1]->setter(1);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: do not use operator[] for unordered_map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void arithmetic() {
+  int A = 1 + IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void comparison() {
+  bool A = IntMap[1] == 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  bool B = FooMap[1] == Foo{};
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void convertedToBool() {
+  if (IntMap[1])
+    // CHECK-MESSAGES: [[@LINE-1]]:7: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+    ;
+}
+
+void thrown() {
+  throw IntMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+  throw FooMap[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: do not use operator[] for map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void writeToMap() {
+  IntMap[1] = 1;
+  FooMap[1] = Foo{};
+  FooPtrMap[1] = new Foo;
+}
+
+void refFromMap() {
+  int &A = IntMap[1];
+  Foo &B = FooMap[1];
+  FooPtr &C = FooPtrMap[1];
+}
+
+void ptrFromMap() {
+  int *A = &IntMap[1];
+  Foo *B = &FooMap[1];
+  FooPtr *C = &FooPtrMap[1];
+}
+
+int &returnRefToInt() {
+  return IntMap[1];
+}
+
+Foo &returnRefToFoo() {
+  return FooMap[1];
+}
+
+FooPtr &returnRefToFooPtr() {
+  return FooPtrMap[1];
+}
+
+int *returnPtrToInt() {
+  return &IntMap[1];
+}
+
+Foo *returnPtrToFoo() {
+  return &FooMap[1];
+}
+
+FooPtr *returnPtrToFooPtr() {
+  return &FooPtrMap[1];
+}
+
+void callWriteX() {
+  writeInt(IntMap[1]);
+  writeFoo(FooMap[1]);
+}
+
+void passAddrToFunctionTakingPtr() {
+  copyFooPtr(&FooMap[1]);
+}
+
+void callMemf() {
+  FooMap[1].setter(1);
+}
+
+void increment() {
+  ++IntMap[1];
+  IntMap[1]++;
+}
+
+void unused() {
+  IntMap[1];
+  FooMap[1];
+  FooPtrMap[1];
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-map-subscript-operator-lookup-custom.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-map-subscript-operator-lookup-custom.cpp
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s bugprone-map-subscript-operator-lookup %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: bugprone-map-subscript-operator-lookup.MapTypes, \
+// RUN:    value: "::ns::Map"}]}' \
+// RUN: --
+
+namespace ns {
+
+template <typename K, typename V>
+struct Map {
+  V &operator[](const K &);
+  V &operator[](K &&);
+};
+
+template <typename K, typename V>
+struct DerivedMap : public Map<K, V> {};
+
+using IntMap = Map<int, int>;
+
+} // namespace ns
+
+void warning() {
+  ns::Map<int, int> M;
+  auto A = M[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: do not use operator[] for Map lookup [bugprone-map-subscript-operator-lookup]
+
+  ns::DerivedMap<int, int> DM;
+  auto B = DM[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: do not use operator[] for Map lookup [bugprone-map-subscript-operator-lookup]
+
+  ns::IntMap IM;
+  auto C = IM[1];
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: do not use operator[] for Map lookup [bugprone-map-subscript-operator-lookup]
+}
+
+void noWarning() {
+  ns::Map<int, int> MOk;
+  MOk[1] = 2;
+
+  ns::DerivedMap<int, int> DMOk;
+  DMOk[1] = 2;
+
+  ns::IntMap IMOk;
+  IMOk[1] = 2;
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -64,6 +64,7 @@
    `bugprone-lambda-function-name <bugprone-lambda-function-name.html>`_,
    `bugprone-macro-parentheses <bugprone-macro-parentheses.html>`_, "Yes"
    `bugprone-macro-repeated-side-effects <bugprone-macro-repeated-side-effects.html>`_,
+   `bugprone-map-subscript-operator-lookup <bugprone-map-subscript-operator-lookup.html>`_,
    `bugprone-misplaced-operator-in-strlen-in-alloc <bugprone-misplaced-operator-in-strlen-in-alloc.html>`_, "Yes"
    `bugprone-misplaced-pointer-arithmetic-in-alloc <bugprone-misplaced-pointer-arithmetic-in-alloc.html>`_, "Yes"
    `bugprone-misplaced-widening-cast <bugprone-misplaced-widening-cast.html>`_,
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-map-subscript-operator-lookup.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-map-subscript-operator-lookup.rst
@@ -0,0 +1,37 @@
+.. title:: clang-tidy - bugprone-map-subscript-operator-lookup
+
+bugprone-map-subscript-operator-lookup
+======================================
+
+Finds map lookups done with ``operator[]``.
+
+Using ``std::map::operator[]`` for finding values from the map is a common
+source of bugs in C++ programs. The operator's side effect of possibly inserting
+a value to the map can easily cause surprises. The usage of the operator can be
+replaced with ``at()`` or ``find()`` in cases where it's used to only look up
+values from the map with no intention of modifying it.
+
+This check warns when the operator is used for map lookup:
+
+.. code-block:: c++
+
+  std::map<int, int> m;
+  const auto i = m[1]; // warning
+
+The check only warns about *lookups* done with ``operator[]``. Modifying the map
+using it is still ok:
+
+.. code-block:: c++
+
+  std::map<int, int> m;
+  m[1] = 2; // ok
+
+In general, doing any mutating operation through the reference returned by the
+operator is allowed by this check. If the reference is used as
+reference-to-const, a warning is given:
+
+.. code-block:: c++
+
+  std::map<int, Foo> m;
+  m[1].setter(1); // ok
+  const auto a = m[1].getter(); // warning
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -75,6 +75,12 @@
 
 New checks
 ^^^^^^^^^^
+
+- New :doc:`bugprone-map-subscript-operator-lookup
+  <clang-tidy/checks/bugprone-map-subscript-operator-lookup>` check.
+
+  Finds map lookups done with ``operator[]``.
+
 - New :doc:`cppcoreguidelines-avoid-non-const-global-variables
   <clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables>` check.
   Finds non-const global variables as described in check I.2 of C++ Core
Index: clang-tools-extra/clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.h
@@ -0,0 +1,38 @@
+//===--- MapSubscriptOperatorLookupCheck.h - clang-tidy ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MAPSUBSCRIPTOPERATORLOOKUPCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MAPSUBSCRIPTOPERATORLOOKUPCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// Detects map lookups done with operator[].
+///
+/// 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);
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  std::string MapTypes;
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MAPSUBSCRIPTOPERATORLOOKUPCHECK_H
Index: clang-tools-extra/clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/MapSubscriptOperatorLookupCheck.cpp
@@ -0,0 +1,70 @@
+//===--- MapSubscriptOperatorLookupCheck.cpp - clang-tidy -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MapSubscriptOperatorLookupCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+MapSubscriptOperatorLookupCheck::MapSubscriptOperatorLookupCheck(
+    llvm::StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      MapTypes(Options.get("MapTypes", "::std::map;::std::unordered_map")) {}
+
+bool MapSubscriptOperatorLookupCheck::isLanguageVersionSupported(
+    const LangOptions &LangOpts) const {
+  return LangOpts.CPlusPlus;
+}
+
+void MapSubscriptOperatorLookupCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "MapTypes", MapTypes);
+}
+
+void MapSubscriptOperatorLookupCheck::registerMatchers(MatchFinder *Finder) {
+  auto MapTypeVec = utils::options::parseStringList(MapTypes);
+  Finder->addMatcher(
+      cxxOperatorCallExpr(
+          callee(cxxMethodDecl(hasName("operator[]"),
+                               ofClass(hasAnyName(std::vector<StringRef>(
+                                   MapTypeVec.begin(), MapTypeVec.end()))))
+                     .bind("operator")),
+          anyOf(
+              // the return value is used in const context
+              hasParent(implicitCastExpr(
+                  anyOf(hasImplicitDestinationType(isConstQualified()),
+                        // for scalar types const usage of the return value is
+                        // seen as lvalue -> rvalue cast
+                        hasCastKind(CK_LValueToRValue)))),
+              // address of the return value is taken, but the resulting pointer
+              // is used as pointer-to-const
+              hasParent(unaryOperator(
+                  hasOperatorName("&"),
+                  hasParent(implicitCastExpr(hasImplicitDestinationType(
+                      pointsTo(isConstQualified()))))))))
+          .bind("call"),
+      this);
+}
+
+void MapSubscriptOperatorLookupCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
+  const auto *Operator = Result.Nodes.getNodeAs<CXXMethodDecl>("operator");
+  diag(Call->getBeginLoc(), "do not use operator[] for %0 lookup")
+      << Operator->getParent()->getName();
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -24,6 +24,7 @@
   LambdaFunctionNameCheck.cpp
   MacroParenthesesCheck.cpp
   MacroRepeatedSideEffectsCheck.cpp
+  MapSubscriptOperatorLookupCheck.cpp
   MisplacedOperatorInStrlenInAllocCheck.cpp
   MisplacedPointerArithmeticInAllocCheck.cpp
   MisplacedWideningCastCheck.cpp
Index: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -29,6 +29,7 @@
 #include "LambdaFunctionNameCheck.h"
 #include "MacroParenthesesCheck.h"
 #include "MacroRepeatedSideEffectsCheck.h"
+#include "MapSubscriptOperatorLookupCheck.h"
 #include "MisplacedOperatorInStrlenInAllocCheck.h"
 #include "MisplacedPointerArithmeticInAllocCheck.h"
 #include "MisplacedWideningCastCheck.h"
@@ -108,6 +109,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<MisplacedPointerArithmeticInAllocCheck>(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to