summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2016-02-11 16:22:58 +0000
committerAlexander Kornienko <alexfh@google.com>2016-02-11 16:22:58 +0000
commit8b251293284247fdf9395d46a948ba8de9b9d5e0 (patch)
tree5bcb885de0284082007a47d595ecd53c0ac25b0f
parent2422234d00b093c75255f21b8ee15495ff419795 (diff)
downloadclang-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.cpp37
-rw-r--r--clang-tidy/google/IntegerTypesCheck.h7
-rw-r--r--test/clang-tidy/google-runtime-int.cpp7
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;
+}