Author: Benedek Kaibas Date: 2026-07-22T22:48:32+02:00 New Revision: 252f31a6893b6a3dcb8b2a404e13933e376bf36b
URL: https://github.com/llvm/llvm-project/commit/252f31a6893b6a3dcb8b2a404e13933e376bf36b DIFF: https://github.com/llvm/llvm-project/commit/252f31a6893b6a3dcb8b2a404e13933e376bf36b.diff LOG: [analyzer] Detect dangling pointers passed to function calls (#211045) In order to detect if a dangling pointer is passed to a function the analyzer has to inspect each call argument. For that reason I have implemented the `checkPostCall` for the `DanglingPtrDeref` checker to check if an argument passed to a function is dangling. Since `checkLocation` only catches dereferences and cannot reason about whether an argument passed to a function is dangling it cannot detect these type of bugs alone. Added: Modified: clang/lib/StaticAnalyzer/Checkers/DanglingPtrDeref.cpp clang/test/Analysis/dangling-ptr-deref.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/DanglingPtrDeref.cpp b/clang/lib/StaticAnalyzer/Checkers/DanglingPtrDeref.cpp index 781045a4d0654..ff2087e1db933 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DanglingPtrDeref.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DanglingPtrDeref.cpp @@ -3,16 +3,18 @@ #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" using namespace clang; using namespace ento; namespace { -class DanglingPtrDeref : public Checker<check::Location> { +class DanglingPtrDeref : public Checker<check::Location, check::PostCall> { public: void checkLocation(SVal Loc, bool IsLoad, const Stmt *S, CheckerContext &C) const; + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void reportUseAfterScope(const MemRegion *Region, ExplodedNode *N, CheckerContext &C) const; const BugType BugMsg{this, "ReportDanglingPtrDeref", "LifetimeBound"}; @@ -48,6 +50,22 @@ void DanglingPtrDeref::checkLocation(SVal Loc, bool IsLoad, const Stmt *S, } } +void DanglingPtrDeref::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + // Only check calls arguments if it is not inlined by the engine. In case a + // function is inlined checkLocation handles any dereference in its body. + if (C.wasInlined) + return; + + for (unsigned Idx = 0; Idx < Call.getNumArgs(); Idx++) { + if (const MemRegion *ArgRegion = Call.getArgSVal(Idx).getAsRegion()) + if (lifetime_modeling::isDeallocated(State, ArgRegion)) + if (ExplodedNode *N = C.generateNonFatalErrorNode()) + reportUseAfterScope(ArgRegion, N, C); + } +} + void DanglingPtrDeref::reportUseAfterScope(const MemRegion *Region, ExplodedNode *N, CheckerContext &C) const { diff --git a/clang/test/Analysis/dangling-ptr-deref.cpp b/clang/test/Analysis/dangling-ptr-deref.cpp index ad6a9aceb5981..e661eff9ccbb6 100644 --- a/clang/test/Analysis/dangling-ptr-deref.cpp +++ b/clang/test/Analysis/dangling-ptr-deref.cpp @@ -84,3 +84,31 @@ void test_case_seven() { // expected-warning@-1 {{Use of 'i' after its lifetime ended}} // expected-note@-2 {{Use of 'i' after its lifetime ended}} } + +void passing_dangling_ptr_to_opaque_func() { + int *ptr = nullptr; + { + int num = 5; + ptr = # + } + // expected-note@-1 {{'num' is destroyed here}} + escape(ptr); + // expected-warning@-1 {{Use of 'num' after its lifetime ended}} + // expected-note@-2 {{Use of 'num' after its lifetime ended}} +} + +int deref_param(int *p) { return *p; } +// expected-warning@-1 {{Use of 'num' after its lifetime ended}} +// expected-note@-2 {{Use of 'num' after its lifetime ended}} + +void inlined_callee_single_report() { + int *ptr = nullptr; + { + int num = 5; + ptr = # + } + // expected-note@-1 {{'num' is destroyed here}} + int r = deref_param(ptr); + // expected-note@-1 {{Calling 'deref_param'}} + (void)r; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
