Skip to content

Commit 9217054

Browse files
committed
implement check
1 parent c13cf10 commit 9217054

File tree

1 file changed

+36
-10
lines changed

1 file changed

+36
-10
lines changed

clang-tools-extra/clang-tidy/bugprone/TrueMacroCheck.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "TrueMacroCheck.h"
10-
#include "clang/ASTMatchers/ASTMatchFinder.h"
1110
#include "clang/Lex/MacroInfo.h"
1211
#include "clang/Lex/PPCallbacks.h"
1312
#include "clang/Lex/Preprocessor.h"
14-
#include <iostream>
1513

1614
using namespace clang::ast_matchers;
1715

@@ -22,11 +20,20 @@ class MacroCallback : public PPCallbacks {
2220
static constexpr const char *TrueMacroSpelling = "true";
2321

2422
public:
25-
MacroCallback(TrueMacroCheck *Check, const SourceManager &SM,
26-
Preprocessor *PP)
27-
: Check(Check), SM(&SM), PP(PP) {}
23+
MacroCallback(TrueMacroCheck *Check, Preprocessor *PP)
24+
: Check(Check), PP(PP) {}
2825
void MacroDefined(const Token &MacroNameTok,
2926
const MacroDirective *MD) override {
27+
if (TrueDefined)
28+
return;
29+
30+
const MacroInfo *MI = MD->getMacroInfo();
31+
for (const Token &Tok : MI->tokens()) {
32+
if (PP->getSpelling(Tok) == TrueMacroSpelling)
33+
emitDiagnostics(Tok.getLocation(),
34+
{Tok.getLocation(), Tok.getEndLoc()});
35+
}
36+
3037
if (PP->getSpelling(MacroNameTok) == TrueMacroSpelling)
3138
TrueDefined = true;
3239
}
@@ -44,12 +51,32 @@ class MacroCallback : public PPCallbacks {
4451
Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange),
4552
PP->getSourceManager(), PP->getLangOpts());
4653

47-
for (auto &&Identifier : identifiersInCondition(Condition))
48-
std::cout << Identifier.str() << ' ' << Identifier.size() << '\n';
54+
if (!TrueDefined && Condition == TrueMacroSpelling) {
55+
emitDiagnostics(ConditionRange.getBegin(), ConditionRange);
56+
return;
57+
}
58+
59+
for (auto &&Identifier : identifiersInCondition(Condition)) {
60+
if (!TrueDefined && Identifier == TrueMacroSpelling) {
61+
emitDiagnostics(Loc, {}, true);
62+
break;
63+
}
64+
}
4965
}
5066

5167
private:
52-
void emitDiagnostic() {}
68+
void emitDiagnostics(SourceLocation Loc, SourceRange ReplaceRange,
69+
bool InCondition = false) {
70+
DiagnosticBuilder Builder =
71+
Check->diag(Loc, "in C 'true'%select{| in the condition}0 is treated "
72+
"as an undefined "
73+
"macro and evaluates to a falsy value; "
74+
"consider replacing it with '1'")
75+
<< InCondition;
76+
77+
if (!InCondition)
78+
Builder << FixItHint::CreateReplacement(ReplaceRange, "1");
79+
}
5380

5481
std::vector<StringRef> identifiersInCondition(StringRef Condition) {
5582
const static auto Start = [](char C) {
@@ -83,15 +110,14 @@ class MacroCallback : public PPCallbacks {
83110
bool TrueDefined = false;
84111

85112
TrueMacroCheck *Check;
86-
const SourceManager *SM;
87113
Preprocessor *PP;
88114
};
89115
} // namespace
90116

91117
void TrueMacroCheck::registerPPCallbacks(const SourceManager &SM,
92118
Preprocessor *PP,
93119
Preprocessor *ModuleExpanderPP) {
94-
PP->addPPCallbacks(std::make_unique<MacroCallback>(this, SM, PP));
120+
PP->addPPCallbacks(std::make_unique<MacroCallback>(this, PP));
95121
}
96122

97123
} // namespace clang::tidy::bugprone

0 commit comments

Comments
 (0)