=?utf-8?q?Kristóf?= Umann <[email protected]>,
=?utf-8?q?Kristóf?= Umann <[email protected]>,
=?utf-8?q?Kristóf?= Umann <[email protected]>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>
================
@@ -696,6 +730,69 @@ struct StreamOperationEvaluator {
} // end anonymous namespace
+//===----------------------------------------------------------------------===//
+// Definition of NoStreamStateChangeVisitor.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class NoStreamStateChangeVisitor final : public NoOwnershipChangeVisitor {
+protected:
+ /// Syntactically checks whether the callee is a freeing function. Since
+ /// we have no path-sensitive information on this call (we would need a
+ /// CallEvent instead of a CallExpr for that), its possible that a
+ /// freeing function was called indirectly through a function pointer,
+ /// but we are not able to tell, so this is a best effort analysis.
+ bool isFreeingCallAsWritten(const CallExpr &Call) const {
+ const auto *StreamChk = static_cast<const StreamChecker *>(&Checker);
+ if (StreamChk->FCloseDesc.matchesAsWritten(Call))
+ return true;
+
+ return false;
+ }
+
+ bool doesFnIntendToHandleOwnership(const Decl *Callee,
+ ASTContext &ACtx) override {
+ using namespace clang::ast_matchers;
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(Callee);
+
+ auto Matches =
+ match(findAll(callExpr().bind("call")), *FD->getBody(), ACtx);
+ for (BoundNodes Match : Matches) {
+ if (const auto *Call = Match.getNodeAs<CallExpr>("call"))
+ if (isFreeingCallAsWritten(*Call))
+ return true;
+ }
+ // TODO: Ownership might change with an attempt to store stream object, not
+ // only through freeing it. Check for attempted stores as well.
+ return false;
+ }
+
+ virtual bool hasResourceStateChanged(ProgramStateRef CallEnterState,
+ ProgramStateRef CallExitEndState) final
{
----------------
steakhal wrote:
For the previous function you used `override`. Here you use both `virtual` and
`final`.
Could you harmonize these by either using `override` or `final` everywhere? I
don't think the `virtual` is every justified as that is implied from these
anyways.
https://github.com/llvm/llvm-project/pull/94957
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits