Skip to content

Commit c13cf10

Browse files
committed
add new check
1 parent e5f5517 commit c13cf10

File tree

8 files changed

+156
-0
lines changed

8 files changed

+156
-0
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#include "TerminatingContinueCheck.h"
8686
#include "ThrowKeywordMissingCheck.h"
8787
#include "TooSmallLoopVariableCheck.h"
88+
#include "TrueMacroCheck.h"
8889
#include "UncheckedOptionalAccessCheck.h"
8990
#include "UndefinedMemoryManipulationCheck.h"
9091
#include "UndelegatedConstructorCheck.h"
@@ -247,6 +248,8 @@ class BugproneModule : public ClangTidyModule {
247248
"bugprone-throw-keyword-missing");
248249
CheckFactories.registerCheck<TooSmallLoopVariableCheck>(
249250
"bugprone-too-small-loop-variable");
251+
CheckFactories.registerCheck<TrueMacroCheck>(
252+
"bugprone-true-macro");
250253
CheckFactories.registerCheck<UncheckedOptionalAccessCheck>(
251254
"bugprone-unchecked-optional-access");
252255
CheckFactories.registerCheck<UndefinedMemoryManipulationCheck>(

clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ add_clang_library(clangTidyBugproneModule STATIC
8686
TerminatingContinueCheck.cpp
8787
ThrowKeywordMissingCheck.cpp
8888
TooSmallLoopVariableCheck.cpp
89+
TrueMacroCheck.cpp
8990
UncheckedOptionalAccessCheck.cpp
9091
UndefinedMemoryManipulationCheck.cpp
9192
UndelegatedConstructorCheck.cpp
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--- TrueMacroCheck.cpp - clang-tidy ----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "TrueMacroCheck.h"
10+
#include "clang/ASTMatchers/ASTMatchFinder.h"
11+
#include "clang/Lex/MacroInfo.h"
12+
#include "clang/Lex/PPCallbacks.h"
13+
#include "clang/Lex/Preprocessor.h"
14+
#include <iostream>
15+
16+
using namespace clang::ast_matchers;
17+
18+
namespace clang::tidy::bugprone {
19+
namespace {
20+
21+
class MacroCallback : public PPCallbacks {
22+
static constexpr const char *TrueMacroSpelling = "true";
23+
24+
public:
25+
MacroCallback(TrueMacroCheck *Check, const SourceManager &SM,
26+
Preprocessor *PP)
27+
: Check(Check), SM(&SM), PP(PP) {}
28+
void MacroDefined(const Token &MacroNameTok,
29+
const MacroDirective *MD) override {
30+
if (PP->getSpelling(MacroNameTok) == TrueMacroSpelling)
31+
TrueDefined = true;
32+
}
33+
34+
virtual void MacroUndefined(const Token &MacroNameTok,
35+
const MacroDefinition &MD,
36+
const MacroDirective *Undef) override {
37+
if (PP->getSpelling(MacroNameTok) == TrueMacroSpelling)
38+
TrueDefined = false;
39+
}
40+
41+
virtual void If(SourceLocation Loc, SourceRange ConditionRange,
42+
ConditionValueKind ConditionValue) override {
43+
StringRef Condition =
44+
Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange),
45+
PP->getSourceManager(), PP->getLangOpts());
46+
47+
for (auto &&Identifier : identifiersInCondition(Condition))
48+
std::cout << Identifier.str() << ' ' << Identifier.size() << '\n';
49+
}
50+
51+
private:
52+
void emitDiagnostic() {}
53+
54+
std::vector<StringRef> identifiersInCondition(StringRef Condition) {
55+
const static auto Start = [](char C) {
56+
return C == '_' || ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z');
57+
};
58+
59+
const static auto Continue = [](char C) {
60+
return ('0' <= C && C <= '9') || Start(C);
61+
};
62+
63+
std::vector<StringRef> Identifiers;
64+
const char *Str = nullptr;
65+
66+
for (size_t I = 0; I < Condition.size(); ++I) {
67+
char C = Condition[I];
68+
69+
if (!Str && Start(C)) {
70+
Str = Condition.begin() + I;
71+
} else if (Str && !Continue(C)) {
72+
Identifiers.emplace_back(Str, Condition.begin() + I - Str);
73+
Str = nullptr;
74+
}
75+
}
76+
77+
if (Str)
78+
Identifiers.emplace_back(Str, Condition.end() - Str);
79+
80+
return Identifiers;
81+
}
82+
83+
bool TrueDefined = false;
84+
85+
TrueMacroCheck *Check;
86+
const SourceManager *SM;
87+
Preprocessor *PP;
88+
};
89+
} // namespace
90+
91+
void TrueMacroCheck::registerPPCallbacks(const SourceManager &SM,
92+
Preprocessor *PP,
93+
Preprocessor *ModuleExpanderPP) {
94+
PP->addPPCallbacks(std::make_unique<MacroCallback>(this, SM, PP));
95+
}
96+
97+
} // namespace clang::tidy::bugprone
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===--- TrueMacroCheck.h - clang-tidy --------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TRUEMACROCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TRUEMACROCHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
14+
namespace clang::tidy::bugprone {
15+
16+
class TrueMacroCheck : public ClangTidyCheck {
17+
public:
18+
TrueMacroCheck(StringRef Name, ClangTidyContext *Context)
19+
: ClangTidyCheck(Name, Context) {}
20+
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
21+
Preprocessor *ModuleExpanderPP) override;
22+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
23+
return !LangOpts.CPlusPlus;
24+
}
25+
};
26+
27+
} // namespace clang::tidy::bugprone
28+
29+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TRUEMACROCHECK_H

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ Improvements to clang-tidy
9191
New checks
9292
^^^^^^^^^^
9393

94+
- New :doc:`bugprone-true-macro
95+
<clang-tidy/checks/bugprone/true-macro>` check.
96+
97+
FIXME: Write a short description.
98+
9499
New check aliases
95100
^^^^^^^^^^^^^^^^^
96101

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.. title:: clang-tidy - bugprone-true-macro
2+
3+
bugprone-true-macro
4+
===================
5+
6+
FIXME: Describe what patterns does the check detect and why. Give examples.

clang-tools-extra/docs/clang-tidy/checks/list.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ Clang-Tidy Checks
153153
:doc:`bugprone-terminating-continue <bugprone/terminating-continue>`, "Yes"
154154
:doc:`bugprone-throw-keyword-missing <bugprone/throw-keyword-missing>`,
155155
:doc:`bugprone-too-small-loop-variable <bugprone/too-small-loop-variable>`,
156+
:doc:`bugprone-true-macro <bugprone/true-macro>`, "Yes"
156157
:doc:`bugprone-unchecked-optional-access <bugprone/unchecked-optional-access>`,
157158
:doc:`bugprone-undefined-memory-manipulation <bugprone/undefined-memory-manipulation>`,
158159
:doc:`bugprone-undelegated-constructor <bugprone/undelegated-constructor>`,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %check_clang_tidy -std=c99-or-later %s bugprone-true-macro %t
2+
3+
// FIXME: Add something that triggers the check here.
4+
void f();
5+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'f' is insufficiently awesome [bugprone-true-macro]
6+
7+
// FIXME: Verify the applied fix.
8+
// * Make the CHECK patterns specific enough and try to make verified lines
9+
// unique to avoid incorrect matches.
10+
// * Use {{}} for regular expressions.
11+
// CHECK-FIXES: {{^}}void awesome_f();{{$}}
12+
13+
// FIXME: Add something that doesn't trigger the check here.
14+
void awesome_f2();

0 commit comments

Comments
 (0)