[PATCH] D63093: [analyzer] WIP: MallocChecker: Release temporary CXXNewExpr
Csaba Dabis via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 10 13:11:51 PDT 2019
Charusso created this revision.
Charusso added reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus.
Charusso added a project: clang.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet.
-
Repository:
rC Clang
https://reviews.llvm.org/D63093
Files:
clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -156,21 +156,14 @@
typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
-class MallocChecker : public Checker<check::DeadSymbols,
- check::PointerEscape,
- check::ConstPointerEscape,
- check::PreStmt<ReturnStmt>,
- check::EndFunction,
- check::PreCall,
- check::PostStmt<CallExpr>,
- check::PostStmt<CXXNewExpr>,
- check::NewAllocator,
- check::PreStmt<CXXDeleteExpr>,
- check::PostStmt<BlockExpr>,
- check::PostObjCMessage,
- check::Location,
- eval::Assume>
-{
+class MallocChecker
+ : public Checker<check::DeadSymbols, check::PointerEscape,
+ check::ConstPointerEscape, check::PreStmt<ReturnStmt>,
+ check::EndFunction, check::PreCall,
+ check::PostStmt<CallExpr>, check::PostStmt<CXXNewExpr>,
+ check::PostStmt<CXXBindTemporaryExpr>, check::NewAllocator,
+ check::PreStmt<CXXDeleteExpr>, check::PostStmt<BlockExpr>,
+ check::PostObjCMessage, check::Location, eval::Assume> {
public:
MallocChecker()
: II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr),
@@ -211,6 +204,7 @@
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
+ void checkPostStmt(const CXXBindTemporaryExpr *BTE, CheckerContext &C) const;
void checkNewAllocator(const CXXNewExpr *NE, SVal Target,
CheckerContext &C) const;
void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
@@ -489,7 +483,8 @@
bool IsReleased = (S && S->isReleased()) &&
(!SPrev || !SPrev->isReleased());
assert(!IsReleased ||
- (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt))) ||
+ (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt) ||
+ isa<CXXBindTemporaryExpr>(Stmt))) ||
(!Stmt && S->getAllocationFamily() == AF_InnerBuffer));
return IsReleased;
}
@@ -1103,6 +1098,34 @@
processNewAllocation(NE, C, Target);
}
+void MallocChecker::checkPostStmt(const CXXBindTemporaryExpr *BTE,
+ CheckerContext &C) const {
+ if (const auto *CE = dyn_cast<CXXConstructExpr>(BTE->getSubExpr())) {
+ if (CE->getNumArgs() == 0)
+ return;
+
+ // If we catch a 'CXXNewExpr' set it is released as it is temporary.
+ if (const auto *NE = dyn_cast<CXXNewExpr>(CE->getArg(0))) {
+ ProgramStateRef State = C.getState();
+ Optional<SVal> RetVal = C.getSVal(NE);
+
+ SymbolRef Sym = RetVal->getAsLocSymbol();
+ assert(Sym);
+
+ if (const RefState *RS = State->get<RegionState>(Sym))
+ if (RS->isReleased())
+ return;
+
+ // Set the symbol's state to Released.
+ State = State->set<RegionState>(
+ Sym, RefState::getReleased(NE->isArray() ? AF_CXXNewArray : AF_CXXNew,
+ NE));
+
+ C.addTransition(State);
+ }
+ }
+}
+
// Sets the extent value of the MemRegion allocated by
// new expression NE to its size in Bytes.
//
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63093.203885.patch
Type: text/x-patch
Size: 3907 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190610/531c4b0e/attachment-0001.bin>
More information about the cfe-commits
mailing list