[clang] [WIP] [analyzer] Refactor MallocChecker to use `BindExpr` in `evalCall` (PR #106081)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 27 09:02:32 PDT 2024
================
@@ -1487,56 +1545,78 @@ void MallocChecker::checkOwnershipAttr(const CallEvent &Call,
C.addTransition(State);
}
-void MallocChecker::checkPostCall(const CallEvent &Call,
- CheckerContext &C) const {
- if (C.wasInlined)
- return;
+bool MallocChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
if (!Call.getOriginExpr())
- return;
+ return false;
ProgramStateRef State = C.getState();
if (const CheckFn *Callback = FreeingMemFnMap.lookup(Call)) {
- (*Callback)(this, Call, C);
- return;
+ (*Callback)(this, State, Call, C);
+ return true;
}
if (const CheckFn *Callback = AllocatingMemFnMap.lookup(Call)) {
- (*Callback)(this, Call, C);
- return;
+ State = MallocBindRetval(C, Call, State, false);
+ (*Callback)(this, State, Call, C);
+ return true;
}
if (const CheckFn *Callback = ReallocatingMemFnMap.lookup(Call)) {
- (*Callback)(this, Call, C);
- return;
+ State = MallocBindRetval(C, Call, State, false);
+ (*Callback)(this, State, Call, C);
+ return true;
}
if (isStandardNewDelete(Call)) {
- checkCXXNewOrCXXDelete(Call, C);
- return;
+ if (isStandardNew(Call))
+ State = MallocBindRetval(C, Call, State, false);
+
+ checkCXXNewOrCXXDelete(State, Call, C);
+ return true;
+ }
+
+ if (const CheckFn *Callback = AllocaMemFnMap.lookup(Call)) {
+ State = MallocBindRetval(C, Call, State, true);
+ (*Callback)(this, State, Call, C);
+ return true;
+ }
+
+ if (isFreeingOwnershipAttrCall(Call)) {
+ checkOwnershipAttr(State, Call, C);
+ return true;
+ }
+
+ if (isAllocatingOwnershipAttrCall(Call)) {
+ State = MallocBindRetval(C, Call, State, false);
+ checkOwnershipAttr(State, Call, C);
+ return true;
}
- checkOwnershipAttr(Call, C);
+ return false;
}
// Performs a 0-sized allocations check.
ProgramStateRef MallocChecker::ProcessZeroAllocCheck(
- const CallEvent &Call, const unsigned IndexOfSizeArg, ProgramStateRef State,
- std::optional<SVal> RetVal) {
+ CheckerContext &C, const CallEvent &Call, const unsigned IndexOfSizeArg,
+ ProgramStateRef State, std::optional<SVal> RetVal) {
if (!State)
return nullptr;
- if (!RetVal)
- RetVal = Call.getReturnValue();
-
const Expr *Arg = nullptr;
if (const CallExpr *CE = dyn_cast<CallExpr>(Call.getOriginExpr())) {
Arg = CE->getArg(IndexOfSizeArg);
+ if (!RetVal)
+ RetVal = State->getSVal(CE, C.getLocationContext());
+ ;
} else if (const CXXNewExpr *NE =
dyn_cast<CXXNewExpr>(Call.getOriginExpr())) {
if (NE->isArray()) {
Arg = *NE->getArraySize();
+ if (!RetVal)
+ RetVal = State->getSVal(NE, C.getLocationContext());
+ ;
----------------
NagyDonat wrote:
You could simplify this part if you replace the two `if (!RetVal) RetVal = ` blocks with a single
```cpp
if (!RetVal)
RetVal = State->getSVal(Call.getOriginExpr(), C.getLocationContext());
```
block placed e.g. at line 1627 (before `assert(Arg);`). Also consider introducing a variable like `auto OrigExpr = Call.getOriginExpr()` because with my suggestion it would be referenced three times.
https://github.com/llvm/llvm-project/pull/106081
More information about the cfe-commits
mailing list