summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp
diff options
context:
space:
mode:
authorGabor Horvath <xazax.hun@gmail.com>2015-12-15 08:47:20 +0000
committerGabor Horvath <xazax.hun@gmail.com>2015-12-15 08:47:20 +0000
commit454564a2d940e28577ef110474b026c568e60f46 (patch)
treece5e40ba1ac16818229d4ad181522d156e6d9951 /clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp
parent6015f5c8237c259ac04c539d55d200baa885a807 (diff)
downloadbcm5719-llvm-454564a2d940e28577ef110474b026c568e60f46.tar.gz
bcm5719-llvm-454564a2d940e28577ef110474b026c568e60f46.zip
[clang-tidy] Check for suspicious string assignments.
It is possible to assign arbitrary integer types to strings. Sometimes it is the result of missing to_string call or apostrophes. Reviewers: alexfh Differential Revision: http://reviews.llvm.org/D15411 llvm-svn: 255630
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp
new file mode 100644
index 00000000000..c9ed466ccc3
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/StringIntegerAssignmentCheck.cpp
@@ -0,0 +1,85 @@
+//===--- StringIntegerAssignmentCheck.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 "StringIntegerAssignmentCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+ Finder->addMatcher(
+ cxxOperatorCallExpr(
+ anyOf(hasOverloadedOperatorName("="),
+ hasOverloadedOperatorName("+=")),
+ callee(cxxMethodDecl(ofClass(classTemplateSpecializationDecl(
+ hasName("::std::basic_string"),
+ hasTemplateArgument(0, refersToType(qualType().bind("type"))))))),
+ hasArgument(1,
+ ignoringImpCasts(expr(hasType(isInteger()),
+ unless(hasType(isAnyCharacter())))
+ .bind("expr"))),
+ unless(isInTemplateInstantiation())),
+ this);
+}
+
+void StringIntegerAssignmentCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Argument = Result.Nodes.getNodeAs<Expr>("expr");
+ SourceLocation Loc = Argument->getLocStart();
+
+ auto Diag =
+ diag(Loc, "an integer is interpreted as a character code when assigning "
+ "it to a string; if this is intended, cast the integer to the "
+ "appropriate character type; if you want a string "
+ "representation, use the appropriate conversion facility");
+
+ if (Loc.isMacroID())
+ return;
+
+ auto CharType = *Result.Nodes.getNodeAs<QualType>("type");
+ bool IsWideCharType = CharType->isWideCharType();
+ if (!CharType->isCharType() && !IsWideCharType)
+ return;
+ bool IsOneDigit = false;
+ bool IsLiteral = false;
+ if (const auto *Literal = dyn_cast<IntegerLiteral>(Argument)) {
+ IsOneDigit = Literal->getValue().getLimitedValue() < 10;
+ IsLiteral = true;
+ }
+
+ SourceLocation EndLoc = Lexer::getLocForEndOfToken(
+ Argument->getLocEnd(), 0, *Result.SourceManager,
+ Result.Context->getLangOpts());
+ if (IsOneDigit) {
+ Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "L'" : "'")
+ << FixItHint::CreateInsertion(EndLoc, "'");
+ return;
+ }
+ if (IsLiteral) {
+ Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "L\"" : "\"")
+ << FixItHint::CreateInsertion(EndLoc, "\"");
+ return;
+ }
+
+ if (getLangOpts().CPlusPlus11) {
+ Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "std::to_wstring("
+ : "std::to_string(")
+ << FixItHint::CreateInsertion(EndLoc, ")");
+ }
+}
+
+} // namespace tidy
+} // namespace clang
OpenPOWER on IntegriCloud