[clang] [analyzer] Modernize FuchsiaHandleChecker (PR #111588)

Pavel Skripkin via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 9 07:51:39 PDT 2024


================
@@ -314,6 +449,127 @@ getFuchsiaHandleSymbols(QualType QT, SVal Arg, ProgramStateRef State) {
   return {};
 }
 
+bool FuchsiaHandleChecker::needsInvalidate(const CallEvent &Call) const {
+  const FunctionDecl *FuncDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
+
+  assert(FuncDecl && "Should have FuncDecl at this point");
+
+  for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
+    if (Arg >= FuncDecl->getNumParams())
+      break;
+    const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
+
+    if (PVD->getType()->isAnyPointerType() &&
+        (hasFuchsiaAttr<ReleaseHandleAttr>(PVD) ||
+         hasFuchsiaAttr<AcquireHandleAttr>(PVD) ||
+         hasFuchsiaUnownedAttr<AcquireHandleAttr>(PVD))) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+ProgramStateRef
+FuchsiaHandleChecker::evalArgsAttrs(const CallEvent &Call, CheckerContext &C,
+                                    ProgramStateRef State) const {
+  const FunctionDecl *FuncDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
+  SymbolRef ResultSymbol = nullptr;
+
+  assert(FuncDecl && "Should have FuncDecl at this point");
+
+  if (const auto *TypeDefTy = FuncDecl->getReturnType()->getAs<TypedefType>())
+    if (TypeDefTy->getDecl()->getName() == ErrorTypeName) {
+      SValBuilder &SVB = C.getSValBuilder();
+      const LocationContext *LC = C.getLocationContext();
+      auto RetVal = SVB.conjureSymbolVal(
+          Call.getOriginExpr(), LC, FuncDecl->getReturnType(), C.blockCount());
+
+      State = State->BindExpr(Call.getOriginExpr(), LC, RetVal);
+      ResultSymbol = RetVal.getAsSymbol();
+    }
+
+  for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
+    if (Arg >= FuncDecl->getNumParams())
+      break;
+    const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
+    SmallVector<SymbolRef, 1024> Handles =
+        getFuchsiaHandleSymbols(PVD->getType(), Call.getArgSVal(Arg), State);
+
+    for (SymbolRef Handle : Handles) {
+      if (hasFuchsiaAttr<ReleaseHandleAttr>(PVD)) {
+        State =
+            State->set<HStateMap>(Handle, HandleState::getReleased(Arg + 1));
+      } else if (hasFuchsiaAttr<AcquireHandleAttr>(PVD)) {
+        State = State->set<HStateMap>(
+            Handle, HandleState::getMaybeAllocated(ResultSymbol, Arg + 1));
+      } else if (hasFuchsiaUnownedAttr<AcquireHandleAttr>(PVD)) {
+        State = State->set<HStateMap>(Handle, HandleState::getUnowned(Arg + 1));
+      }
+    }
+  }
+
+  return State;
+}
+
+ProgramStateRef FuchsiaHandleChecker::evalFunctionAttrs(
+    const CallEvent &Call, CheckerContext &C, ProgramStateRef State) const {
+  const FunctionDecl *FuncDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
+
+  assert(FuncDecl && "Should have FuncDecl at this point");
+
+  if (!hasFuchsiaAttr<AcquireHandleAttr>(FuncDecl) &&
+      !hasFuchsiaUnownedAttr<AcquireHandleAttr>(FuncDecl))
+    return State;
+
+  SValBuilder &SVB = C.getSValBuilder();
+  const LocationContext *LC = C.getLocationContext();
+  auto RetVal = SVB.conjureSymbolVal(Call.getOriginExpr(), LC,
+                                     FuncDecl->getReturnType(), C.blockCount());
+  State = State->BindExpr(Call.getOriginExpr(), LC, RetVal);
----------------
pskrgag wrote:

Redone logic a bit. Now return value is always bound if checker models a call

https://github.com/llvm/llvm-project/pull/111588


More information about the cfe-commits mailing list