xazax.hun created this revision. xazax.hun added reviewers: NoQ, Szelethus, baloghadamsoftware, dcoughlin, haowei. xazax.hun added a project: clang. Herald added subscribers: Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet. xazax.hun added a comment.
So some of the questions that came to my mind: 1. Should this be exposed to the checkers? 2. Where should we actually have this trait registered? ProgramState? ExprEngine? Both of them need access, and due to layering I feel like it cannot be in ExprEngine but I might be wrong. This is working progress but I wanted to share early to discuss the direction. This looks relatively painless so far, but note that the locals are not cleaned up from the state just yet. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D71152 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/lib/StaticAnalyzer/Core/ProgramState.cpp clang/test/Analysis/symbol-escape.cpp
Index: clang/test/Analysis/symbol-escape.cpp =================================================================== --- clang/test/Analysis/symbol-escape.cpp +++ clang/test/Analysis/symbol-escape.cpp @@ -31,3 +31,13 @@ return Baz; } +void save_ptr(int **); +void delete_saved(); + +void store_to_escaped_region() { + int *p; + save_ptr(&p); + p = new int; + delete_saved(); +} // no-warning: + Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -16,6 +16,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "llvm/Support/raw_ostream.h" @@ -41,7 +42,23 @@ Mgr.freeStates.push_back(s); } } -}} +} // namespace ento +} // namespace clang + +namespace { +struct EscapedLocals{}; +} // namespace + +template <> +struct ProgramStateTrait<EscapedLocals> : + public ProgramStatePartialTrait<llvm::ImmutableSet<const MemRegion *>> { + static void *GDMIndex(); +}; + +void *ProgramStateTrait<EscapedLocals>::GDMIndex() { + static int index = 0; + return &index; +} ProgramState::ProgramState(ProgramStateManager *mgr, const Environment& env, StoreRef st, GenericDataMap gdm) @@ -209,6 +226,12 @@ ProgramStateRef newState = makeWithStore(newStore); if (CausedByPointerEscape) { + for (const MemRegion *R : Invalidated) { + if (!R->hasStackStorage()) + continue; + newState = newState->add<EscapedLocals>(R); + } + newState = Eng.notifyCheckersOfPointerEscape(newState, IS, TopLevelInvalidated, Call, @@ -642,3 +665,7 @@ } return true; } + +bool ProgramState::isEscapedLocal(const MemRegion *R) const { + return this->contains<EscapedLocals>(R); +} Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2680,7 +2680,8 @@ // A value escapes in four possible cases: // (1) We are binding to something that is not a memory region. -// (2) We are binding to a MemRegion that does not have stack storage. +// (2) We are binding to a MemRegion that does not have stack storage +// or the stack storage is escaped. // (3) We are binding to a top-level parameter region with a non-trivial // destructor. We won't see the destructor during analysis, but it's there. // (4) We are binding to a MemRegion with stack storage that the store @@ -2691,7 +2692,7 @@ // Cases (1) and (2). const MemRegion *MR = Loc.getAsRegion(); - if (!MR || !MR->hasStackStorage()) + if (!MR || !MR->hasStackStorage() || State->isEscapedLocal(MR)) return escapeValue(State, Val, PSK_EscapeOnBind); // Case (3). Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -345,6 +345,9 @@ /// a value of such type. SVal getSValAsScalarOrLoc(const MemRegion *R) const; + /// TODO + bool isEscapedLocal(const MemRegion *R) const; + using region_iterator = const MemRegion **; /// Visits the symbols reachable from the given SVal using the provided @@ -872,8 +875,8 @@ bool scan(const SymExpr *sym); }; -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits