;
29enum classObjectState :
bool{ CtorCalled, DtorCalled };
35 static inline void Profile(ObjectState
X, FoldingSetNodeID &ID) {
36ID.AddInteger(
static_cast<int>(
X));
42classVirtualCallChecker
43:
public Checker<check::BeginFunction, check::EndFunction, check::PreCall> {
46 mutablestd::unique_ptr<BugType> BT_Pure, BT_Impure;
47 boolShowFixIts =
false;
54 voidregisterCtorDtorCallInState(
boolIsBeginFunction,
64 boolCallIsNonVirtual =
false;
66 if(
const MemberExpr*CME = dyn_cast<MemberExpr>(CE->getCallee())) {
69 if(CME->getQualifier())
70CallIsNonVirtual =
true;
72 if(
const Expr*
Base= CME->getBase()) {
74 if(
Base->getBestDynamicClassType()->hasAttr<FinalAttr>())
75CallIsNonVirtual =
true;
80dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
81 if(MD && MD->
isVirtual() && !CallIsNonVirtual && !MD->
hasAttr<FinalAttr>() &&
88voidVirtualCallChecker::checkBeginFunction(
CheckerContext&
C)
const{
89registerCtorDtorCallInState(
true,
C);
93voidVirtualCallChecker::checkEndFunction(
const ReturnStmt*RS,
95registerCtorDtorCallInState(
false,
C);
98voidVirtualCallChecker::checkPreCall(
const CallEvent&
Call,
100 const autoMC = dyn_cast<CXXMemberCall>(&
Call);
110 const auto*CE = cast<CallExpr>(
Call.getOriginExpr());
114 const MemRegion*Reg = MC->getCXXThisVal().getAsRegion();
115 constObjectState *ObState = State->get<CtorDtorMap>(Reg);
124llvm::raw_svector_ostream OS(Msg);
130 if(*ObState == ObjectState::CtorCalled)
131OS <<
"construction ";
133OS <<
"destruction ";
135OS <<
"has undefined behavior";
137OS <<
"bypasses virtual dispatch";
140IsPure ?
C.generateErrorNode() :
C.generateNonFatalErrorNode();
144 conststd::unique_ptr<BugType> &BT = IsPure ? BT_Pure : BT_Impure;
150 auto Report= std::make_unique<PathSensitiveBugReport>(*BT, OS.str(), N);
152 if(ShowFixIts && !IsPure) {
159 Report->addFixItHint(Fixit);
162 C.emitReport(std::move(
Report));
165voidVirtualCallChecker::registerCtorDtorCallInState(
boolIsBeginFunction,
167 const auto*LCtx =
C.getLocationContext();
168 const auto*MD = dyn_cast_or_null<CXXMethodDecl>(LCtx->getDecl());
173 auto&SVB =
C.getSValBuilder();
176 if(isa<CXXConstructorDecl>(MD)) {
178State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame()));
179 const MemRegion*Reg = ThiSVal.getAsRegion();
181State = State->set<CtorDtorMap>(Reg, ObjectState::CtorCalled);
183State = State->remove<CtorDtorMap>(Reg);
185 C.addTransition(State);
190 if(isa<CXXDestructorDecl>(MD)) {
192State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame()));
193 const MemRegion*Reg = ThiSVal.getAsRegion();
195State = State->set<CtorDtorMap>(Reg, ObjectState::DtorCalled);
197State = State->remove<CtorDtorMap>(Reg);
199 C.addTransition(State);
209 auto*Chk = Mgr.
getChecker<VirtualCallChecker>();
211 "Pure virtual method call",
216 auto*Chk = Mgr.
getChecker<VirtualCallChecker>();
219Chk->BT_Impure = std::make_unique<BugType>(
227boolento::shouldRegisterVirtualCallModeling(
const CheckerManager&mgr) {
232boolento::shouldRegisterPureVirtualCallChecker(
const CheckerManager&mgr) {
237boolento::shouldRegisterVirtualCallChecker(
const CheckerManager&mgr) {
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
static bool isVirtualCall(const CallExpr *CE)
bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Interprets an option's string value as a boolean.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
This represents one expression.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Represents an abstract call to a function or method along a particular path.
const AnalyzerOptions & getAnalyzerOptions() const
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
const LangOptions & getLangOpts() const
CheckerNameRef getCurrentCheckerName() const
MemRegion - The root abstract class for all memory regions.
const char *const CXXObjectLifecycle
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
static void Profile(ObjectState X, FoldingSetNodeID &ID)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4