Skip to content

Commit 7c1f473

Browse files
authored
[NFC][analyzer] Multipart checker refactor 1: VirtualCallChecker (llvm#132072)
Simplify `VirtualCallChecker.cpp` with the help of the new framework for multipart checkers that was introduced by commit 2709998. This is part of a commit series that will perform analogous changes in all checker classes that implement multiple user-facing checker parts (with separate names). In this commit I'm removing the undocumented hidden `cplusplus.VirtualCallModeling` checker, because (to my best understanding) it was just a hacky implementation detail within the old way of registering the "real" checker parts. Note that keeping or re-adding an extra checker part like this modeling checker would be very easy within the new framework; I'm removing it only because I'm convinced that it is no longer useful.
1 parent 03ceb26 commit 7c1f473

File tree

2 files changed

+26
-39
lines changed

2 files changed

+26
-39
lines changed

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -694,15 +694,11 @@ def MoveChecker: Checker<"Move">,
694694
]>,
695695
Documentation<HasDocumentation>;
696696

697-
def VirtualCallModeling : Checker<"VirtualCallModeling">,
698-
HelpText<"Auxiliary modeling for the virtual method call checkers">,
699-
Documentation<NotDocumented>,
700-
Hidden;
701-
702-
def PureVirtualCallChecker : Checker<"PureVirtualCall">,
703-
HelpText<"Check pure virtual function calls during construction/destruction">,
704-
Dependencies<[VirtualCallModeling]>,
705-
Documentation<HasDocumentation>;
697+
def PureVirtualCallChecker
698+
: Checker<"PureVirtualCall">,
699+
HelpText<
700+
"Check pure virtual function calls during construction/destruction">,
701+
Documentation<HasDocumentation>;
706702
} // end: "cplusplus"
707703

708704
let ParentPackage = CplusplusOptIn in {
@@ -756,7 +752,6 @@ def VirtualCallChecker
756752
CheckerOptions<[CmdLineOption<Boolean, "ShowFixIts",
757753
"Enable fix-it hints for this checker",
758754
"false", InAlpha>]>,
759-
Dependencies<[VirtualCallModeling]>,
760755
Documentation<HasDocumentation>;
761756

762757
} // end: "optin.cplusplus"

clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,14 @@ namespace {
4242
class VirtualCallChecker
4343
: public Checker<check::BeginFunction, check::EndFunction, check::PreCall> {
4444
public:
45-
// These are going to be null if the respective check is disabled.
46-
mutable std::unique_ptr<BugType> BT_Pure, BT_Impure;
45+
enum : CheckerPartIdx { PureChecker, ImpureChecker, NumCheckerParts };
46+
47+
BugType BugTypes[NumCheckerParts] = {
48+
{this, PureChecker, "Pure virtual method call",
49+
categories::CXXObjectLifecycle},
50+
{this, ImpureChecker, "Unexpected loss of virtual dispatch",
51+
categories::CXXObjectLifecycle}};
52+
4753
bool ShowFixIts = false;
4854

4955
void checkBeginFunction(CheckerContext &C) const;
@@ -141,13 +147,15 @@ void VirtualCallChecker::checkPreCall(const CallEvent &Call,
141147
if (!N)
142148
return;
143149

144-
const std::unique_ptr<BugType> &BT = IsPure ? BT_Pure : BT_Impure;
145-
if (!BT) {
150+
const CheckerPartIdx Part = IsPure ? PureChecker : ImpureChecker;
151+
152+
if (!isPartEnabled(Part)) {
146153
// The respective check is disabled.
147154
return;
148155
}
149156

150-
auto Report = std::make_unique<PathSensitiveBugReport>(*BT, OS.str(), N);
157+
auto Report =
158+
std::make_unique<PathSensitiveBugReport>(BugTypes[Part], OS.str(), N);
151159

152160
if (ShowFixIts && !IsPure) {
153161
// FIXME: These hints are valid only when the virtual call is made
@@ -201,37 +209,21 @@ void VirtualCallChecker::registerCtorDtorCallInState(bool IsBeginFunction,
201209
}
202210
}
203211

204-
void ento::registerVirtualCallModeling(CheckerManager &Mgr) {
205-
Mgr.registerChecker<VirtualCallChecker>();
212+
void ento::registerPureVirtualCallChecker(CheckerManager &Mgr) {
213+
Mgr.registerChecker<VirtualCallChecker, VirtualCallChecker::PureChecker>();
206214
}
207215

208-
void ento::registerPureVirtualCallChecker(CheckerManager &Mgr) {
209-
auto *Chk = Mgr.getChecker<VirtualCallChecker>();
210-
Chk->BT_Pure = std::make_unique<BugType>(Mgr.getCurrentCheckerName(),
211-
"Pure virtual method call",
212-
categories::CXXObjectLifecycle);
216+
bool ento::shouldRegisterPureVirtualCallChecker(const CheckerManager &Mgr) {
217+
return Mgr.getLangOpts().CPlusPlus;
213218
}
214219

215220
void ento::registerVirtualCallChecker(CheckerManager &Mgr) {
216-
auto *Chk = Mgr.getChecker<VirtualCallChecker>();
217-
Chk->BT_Impure = std::make_unique<BugType>(
218-
Mgr.getCurrentCheckerName(), "Unexpected loss of virtual dispatch",
219-
categories::CXXObjectLifecycle);
221+
auto *Chk = Mgr.registerChecker<VirtualCallChecker,
222+
VirtualCallChecker::ImpureChecker>();
220223
Chk->ShowFixIts = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
221224
Mgr.getCurrentCheckerName(), "ShowFixIts");
222225
}
223226

224-
bool ento::shouldRegisterVirtualCallModeling(const CheckerManager &mgr) {
225-
const LangOptions &LO = mgr.getLangOpts();
226-
return LO.CPlusPlus;
227-
}
228-
229-
bool ento::shouldRegisterPureVirtualCallChecker(const CheckerManager &mgr) {
230-
const LangOptions &LO = mgr.getLangOpts();
231-
return LO.CPlusPlus;
232-
}
233-
234-
bool ento::shouldRegisterVirtualCallChecker(const CheckerManager &mgr) {
235-
const LangOptions &LO = mgr.getLangOpts();
236-
return LO.CPlusPlus;
227+
bool ento::shouldRegisterVirtualCallChecker(const CheckerManager &Mgr) {
228+
return Mgr.getLangOpts().CPlusPlus;
237229
}

0 commit comments

Comments
 (0)