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

DonĂ¡t Nagy via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 9 08:41:31 PDT 2024


================
@@ -314,6 +329,193 @@ getFuchsiaHandleSymbols(QualType QT, SVal Arg, ProgramStateRef State) {
   return {};
 }
 
+FuchsiaHandleChecker::Note FuchsiaHandleChecker::createNote(
+    SymbolRef Sym,
+    std::function<void(llvm::raw_string_ostream &)> Message) const {
+  return [Sym, Message](BugReport &BR) -> std::string {
+    auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
+    if (!PathBR->getInterestingnessKind(Sym))
+      return "";
+    std::string SBuf;
+    llvm::raw_string_ostream OS(SBuf);
+    Message(OS);
+    return SBuf;
+  };
+}
+
+bool FuchsiaHandleChecker::needsEval(const CallEvent &Call) 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 true;
+
+  for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
+    if (Arg >= FuncDecl->getNumParams())
+      break;
+    const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
+
+    if (hasFuchsiaAttr<ReleaseHandleAttr>(PVD) ||
+        hasFuchsiaAttr<AcquireHandleAttr>(PVD) ||
+        hasFuchsiaUnownedAttr<AcquireHandleAttr>(PVD))
+      return true;
+  }
+
+  return false;
+}
+
+ProgramStateRef FuchsiaHandleChecker::evalArgsAttrs(const CallEvent &Call,
+                                                    CheckerContext &C,
+                                                    ProgramStateRef State,
+                                                    NotesVec &Notes) 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) {
+      ResultSymbol =
+          State->getSVal(Call.getOriginExpr(), C.getLocationContext())
+              .getAsSymbol();
+      assert(ResultSymbol && "Result symbol should be there");
+    }
+
+  for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
+    if (Arg >= FuncDecl->getNumParams())
+      break;
+    const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
+    unsigned ParamDiagIdx = PVD->getFunctionScopeIndex() + 1;
+    SmallVector<SymbolRef> Handles =
+        getFuchsiaHandleSymbols(PVD->getType(), Call.getArgSVal(Arg), State);
+
+    for (SymbolRef Handle : Handles) {
+      if (hasFuchsiaAttr<ReleaseHandleAttr>(PVD)) {
+        Notes.push_back(
+            createNote(Handle, [ParamDiagIdx](llvm::raw_string_ostream &OS) {
+              OS << "Handle released through " << ParamDiagIdx
+                 << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
+            }));
----------------
NagyDonat wrote:

Instead of using lambdas and ostream write operations, this could be implemented even more elegantly with `llvm::formatv`.

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


More information about the cfe-commits mailing list