clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

StringIntegerAssignmentCheck.cpp
Go to the documentation of this file.
1 //===--- StringIntegerAssignmentCheck.cpp - clang-tidy---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "StringIntegerAssignmentCheck.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
14
15 using namespace clang::ast_matchers;
16
17 namespace clang {
18 namespace tidy {
19
20 void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) {
21 if (!getLangOpts().CPlusPlus)
22 return;
23 Finder->addMatcher(
24 cxxOperatorCallExpr(
25 anyOf(hasOverloadedOperatorName("="),
26 hasOverloadedOperatorName("+=")),
27 callee(cxxMethodDecl(ofClass(classTemplateSpecializationDecl(
28 hasName("::std::basic_string"),
29 hasTemplateArgument(0, refersToType(qualType().bind("type"))))))),
30 hasArgument(1,
31 ignoringImpCasts(expr(hasType(isInteger()),
32 unless(hasType(isAnyCharacter())))
33 .bind("expr"))),
34 unless(isInTemplateInstantiation())),
35 this);
36 }
37
38 void StringIntegerAssignmentCheck::check(
39 const MatchFinder::MatchResult &Result) {
40 const auto *Argument = Result.Nodes.getNodeAs<Expr>("expr");
41 SourceLocation Loc = Argument->getLocStart();
42
43 auto Diag =
44 diag(Loc, "an integer is interpreted as a character code when assigning "
45 "it to a string; if this is intended, cast the integer to the "
46 "appropriate character type; if you want a string "
47 "representation, use the appropriate conversion facility");
48
49 if (Loc.isMacroID())
50 return;
51
52 auto CharType = *Result.Nodes.getNodeAs<QualType>("type");
53 bool IsWideCharType = CharType->isWideCharType();
54 if (!CharType->isCharType() && !IsWideCharType)
55 return;
56 bool IsOneDigit = false;
57 bool IsLiteral = false;
58 if (const auto *Literal = dyn_cast<IntegerLiteral>(Argument)) {
59 IsOneDigit = Literal->getValue().getLimitedValue() < 10;
60 IsLiteral = true;
61 }
62
63 SourceLocation EndLoc = Lexer::getLocForEndOfToken(
64 Argument->getLocEnd(), 0, *Result.SourceManager,
65 Result.Context->getLangOpts());
66 if (IsOneDigit) {
67 Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "L'" : "'")
68 << FixItHint::CreateInsertion(EndLoc, "'");
69 return;
70 }
71 if (IsLiteral) {
72 Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "L\"" : "\"")
73 << FixItHint::CreateInsertion(EndLoc, "\"");
74 return;
75 }
76
77 if (getLangOpts().CPlusPlus11) {
78 Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "std::to_wstring("
79 : "std::to_string(")
80 << FixItHint::CreateInsertion(EndLoc, ")");
81 }
82 }
83
84 } // namespace tidy
85 } // namespace clang
Loc
SourceLocation Loc
'#' location in the include directive
Definition: IncludeOrderCheck.cpp:34
Argument
This class represents one callback function argument by name and value.
Definition: PPCallbacksTracker.h:30
StringIntegerAssignmentCheck.h
Finder
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
Result
const NamedDecl * Result
Definition: USRFinder.cpp:121