Author: Florian Mayer Date: 2026-02-05T10:21:03-08:00 New Revision: 483d9bb9e4a15bb24bbd09196f045845650dee7e
URL: https://github.com/llvm/llvm-project/commit/483d9bb9e4a15bb24bbd09196f045845650dee7e DIFF: https://github.com/llvm/llvm-project/commit/483d9bb9e4a15bb24bbd09196f045845650dee7e.diff LOG: [FlowSensitive] [StatusOr] cache pointers for all const methods This is important to support iterators, that often return pairs containing StatusOr. Pull Request: https://github.com/llvm/llvm-project/pull/179791 Added: Modified: clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp index 94aa05559c5db..6aa7efe176c72 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp @@ -252,18 +252,16 @@ static auto isConstStatusOrAccessorMemberOperatorCall() { returns(possiblyReferencedStatusOrType())))); } -static auto isConstStatusOrPointerAccessorMemberCall() { +static auto isConstPointerAccessorMemberCall() { using namespace ::clang::ast_matchers; // NOLINT: Too many names - return cxxMemberCallExpr(callee(cxxMethodDecl( - parameterCountIs(0), isConst(), - returns(pointerType(pointee(possiblyReferencedStatusOrType())))))); + return cxxMemberCallExpr(callee( + cxxMethodDecl(parameterCountIs(0), isConst(), returns(pointerType())))); } -static auto isConstStatusOrPointerAccessorMemberOperatorCall() { +static auto isConstPointerAccessorMemberOperatorCall() { using namespace ::clang::ast_matchers; // NOLINT: Too many names - return cxxOperatorCallExpr(callee(cxxMethodDecl( - parameterCountIs(0), isConst(), - returns(pointerType(pointee(possiblyReferencedStatusOrType())))))); + return cxxOperatorCallExpr(callee( + cxxMethodDecl(parameterCountIs(0), isConst(), returns(pointerType())))); } static auto isNonConstMemberCall() { @@ -903,7 +901,7 @@ static void handleConstStatusOrAccessorMemberCall( if (!doHandleConstStatusOrAccessorMemberCall(Expr, RecordLoc, Result, State)) transferStatusOrReturningCall(Expr, State); } -static void handleConstStatusOrPointerAccessorMemberCall( +static void handleConstPointerAccessorMemberCall( const CallExpr *Expr, RecordStorageLocation *RecordLoc, const MatchFinder::MatchResult &Result, LatticeTransferState &State) { if (RecordLoc == nullptr) @@ -929,19 +927,20 @@ static void transferConstStatusOrAccessorMemberOperatorCall( handleConstStatusOrAccessorMemberCall(Expr, RecordLoc, Result, State); } -static void transferConstStatusOrPointerAccessorMemberCall( - const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &Result, - LatticeTransferState &State) { - handleConstStatusOrPointerAccessorMemberCall( +static void +transferConstPointerAccessorMemberCall(const CXXMemberCallExpr *Expr, + const MatchFinder::MatchResult &Result, + LatticeTransferState &State) { + handleConstPointerAccessorMemberCall( Expr, getImplicitObjectLocation(*Expr, State.Env), Result, State); } -static void transferConstStatusOrPointerAccessorMemberOperatorCall( +static void transferConstPointerAccessorMemberOperatorCall( const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State) { auto *RecordLoc = cast_or_null<RecordStorageLocation>( State.Env.getStorageLocation(*Expr->getArg(0))); - handleConstStatusOrPointerAccessorMemberCall(Expr, RecordLoc, Result, State); + handleConstPointerAccessorMemberCall(Expr, RecordLoc, Result, State); } static void handleNonConstMemberCall(const CallExpr *Expr, @@ -1270,12 +1269,11 @@ buildTransferMatchSwitch(ASTContext &Ctx, .CaseOfCFGStmt<CXXOperatorCallExpr>( isConstStatusOrAccessorMemberOperatorCall(), transferConstStatusOrAccessorMemberOperatorCall) - .CaseOfCFGStmt<CXXMemberCallExpr>( - isConstStatusOrPointerAccessorMemberCall(), - transferConstStatusOrPointerAccessorMemberCall) + .CaseOfCFGStmt<CXXMemberCallExpr>(isConstPointerAccessorMemberCall(), + transferConstPointerAccessorMemberCall) .CaseOfCFGStmt<CXXOperatorCallExpr>( - isConstStatusOrPointerAccessorMemberOperatorCall(), - transferConstStatusOrPointerAccessorMemberOperatorCall) + isConstPointerAccessorMemberOperatorCall(), + transferConstPointerAccessorMemberOperatorCall) // non-const member calls that may modify the state of an object. .CaseOfCFGStmt<CXXMemberCallExpr>(isNonConstMemberCall(), transferNonConstMemberCall) diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp index 3daf4473b0b81..cdc870315016f 100644 --- a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp +++ b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp @@ -3970,8 +3970,7 @@ TEST_P(UncheckedStatusOrAccessModelTest, PairIterator) { }; void target() { if (auto it = Make<iterator>(); it->second.ok()) { - // This is a false positive. Fix and remove the unsafe. - it->second.value(); // [[unsafe]] + it->second.value(); } } )cc"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
