================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits