diff options
author | Alexander Kornienko <alexfh@google.com> | 2016-02-11 16:22:58 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2016-02-11 16:22:58 +0000 |
commit | 8b251293284247fdf9395d46a948ba8de9b9d5e0 (patch) | |
tree | 5bcb885de0284082007a47d595ecd53c0ac25b0f | |
parent | 2422234d00b093c75255f21b8ee15495ff419795 (diff) | |
download | clang-tools-extra-8b251293284247fdf9395d46a948ba8de9b9d5e0.tar.gz |
[clang-tidy] google-runtime-int: fix a false positive in implicit code.
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@260535 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | clang-tidy/google/IntegerTypesCheck.cpp | 37 | ||||
-rw-r--r-- | clang-tidy/google/IntegerTypesCheck.h | 7 | ||||
-rw-r--r-- | test/clang-tidy/google-runtime-int.cpp | 7 |
3 files changed, 48 insertions, 3 deletions
diff --git a/clang-tidy/google/IntegerTypesCheck.cpp b/clang-tidy/google/IntegerTypesCheck.cpp index 0ac31240..00458129 100644 --- a/clang-tidy/google/IntegerTypesCheck.cpp +++ b/clang-tidy/google/IntegerTypesCheck.cpp @@ -12,14 +12,34 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Lex/Lexer.h" namespace clang { + +using namespace ast_matchers; + +static Token getTokenAtLoc(SourceLocation Loc, + const MatchFinder::MatchResult &MatchResult, + IdentifierTable &IdentTable) { + Token Tok; + if (Lexer::getRawToken(Loc, Tok, *MatchResult.SourceManager, + MatchResult.Context->getLangOpts(), false)) + return Tok; + + if (Tok.is(tok::raw_identifier)) { + IdentifierInfo &Info = IdentTable.get(Tok.getRawIdentifier()); + Tok.setIdentifierInfo(&Info); + Tok.setKind(Info.getTokenID()); + } + return Tok; +} + namespace tidy { namespace google { namespace runtime { -using namespace ast_matchers; IntegerTypesCheck::IntegerTypesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -35,8 +55,10 @@ void IntegerTypesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void IntegerTypesCheck::registerMatchers(MatchFinder *Finder) { // Find all TypeLocs. The relevant Style Guide rule only applies to C++. - if (getLangOpts().CPlusPlus) - Finder->addMatcher(typeLoc(loc(isInteger())).bind("tl"), this); + if (!getLangOpts().CPlusPlus) + return; + Finder->addMatcher(typeLoc(loc(isInteger())).bind("tl"), this); + IdentTable = llvm::make_unique<IdentifierTable>(getLangOpts()); } void IntegerTypesCheck::check(const MatchFinder::MatchResult &Result) { @@ -54,6 +76,15 @@ void IntegerTypesCheck::check(const MatchFinder::MatchResult &Result) { if (!BuiltinLoc) return; + Token Tok = getTokenAtLoc(Loc, Result, *IdentTable); + // Ensure the location actually points to one of the builting integral type + // names we're interested in. Otherwise, we might be getting this match from + // implicit code (e.g. an implicit assignment operator of a class containing + // an array of non-POD types). + if (!Tok.isOneOf(tok::kw_short, tok::kw_long, tok::kw_unsigned, + tok::kw_signed)) + return; + bool IsSigned; unsigned Width; const TargetInfo &TargetInfo = Result.Context->getTargetInfo(); diff --git a/clang-tidy/google/IntegerTypesCheck.h b/clang-tidy/google/IntegerTypesCheck.h index c7193c0e..8d8f9038 100644 --- a/clang-tidy/google/IntegerTypesCheck.h +++ b/clang-tidy/google/IntegerTypesCheck.h @@ -12,7 +12,12 @@ #include "../ClangTidy.h" +#include <memory> + namespace clang { + +class IdentifierTable; + namespace tidy { namespace google { namespace runtime { @@ -32,6 +37,8 @@ private: const std::string UnsignedTypePrefix; const std::string SignedTypePrefix; const std::string TypeSuffix; + + std::unique_ptr<IdentifierTable> IdentTable; }; } // namespace runtime diff --git a/test/clang-tidy/google-runtime-int.cpp b/test/clang-tidy/google-runtime-int.cpp index bcf6eb60..e51ca7de 100644 --- a/test/clang-tidy/google-runtime-int.cpp +++ b/test/clang-tidy/google-runtime-int.cpp @@ -65,3 +65,10 @@ struct some_value {}; constexpr some_value operator"" _some_literal(unsigned long long int i); // CHECK-MESSAGES: [[@LINE-1]]:47: warning: consider replacing 'unsigned long long' +struct A { A& operator=(const A&); }; +class B { A a[0]; }; + +void fff() { + B a, b; + a = b; +} |