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