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