[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