diff options
author | Anna Zaks <ganna@apple.com> | 2013-03-28 23:15:29 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-03-28 23:15:29 +0000 |
commit | 41988f331a74a72cf243a2a68ffb56418e9a174e (patch) | |
tree | ab722ed0a8b1c5b6686d45cf7765b0e85564d7a8 /include/clang/StaticAnalyzer | |
parent | aabb4c5eacca6d78ef778f33ec5cd4c755d71a39 (diff) |
[analyzer] Add support for escape of const pointers and use it to allow “newed” pointers to escape
Add a new callback that notifies checkers when a const pointer escapes. Currently, this only works
for const pointers passed as a top level parameter into a function. We need to differentiate the const
pointers escape from regular escape since the content pointed by const pointer will not change;
if it’s a file handle, a file cannot be closed; but delete is allowed on const pointers.
This should suppress several false positives reported by the NewDelete checker on llvm codebase.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178310 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/StaticAnalyzer')
5 files changed, 52 insertions, 11 deletions
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 305ae2579d..0dbaab033d 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -324,11 +324,14 @@ class PointerEscape { ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, - PointerEscapeKind Kind) { - return ((const CHECKER *)checker)->checkPointerEscape(State, - Escaped, - Call, - Kind); + PointerEscapeKind Kind, + bool IsConst) { + if (!IsConst) + return ((const CHECKER *)checker)->checkPointerEscape(State, + Escaped, + Call, + Kind); + return State; } public: @@ -340,6 +343,33 @@ public: } }; +class ConstPointerEscape { + template <typename CHECKER> + static ProgramStateRef + _checkConstPointerEscape(void *checker, + ProgramStateRef State, + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind, + bool IsConst) { + if (IsConst) + return ((const CHECKER *)checker)->checkConstPointerEscape(State, + Escaped, + Call, + Kind); + return State; + } + +public: + template <typename CHECKER> + static void _register(CHECKER *checker, CheckerManager &mgr) { + mgr._registerForPointerEscape( + CheckerManager::CheckPointerEscapeFunc(checker, + _checkConstPointerEscape<CHECKER>)); + } +}; + + template <typename EVENT> class Event { template <typename CHECKER> diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 4353ebf015..6f99fc1457 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -346,12 +346,14 @@ public: /// \param Escaped The list of escaped symbols. /// \param Call The corresponding CallEvent, if the symbols escape as /// parameters to the given call. + /// \param IsConst Specifies if the pointer is const. /// \returns Checkers can modify the state by returning a new one. ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, - PointerEscapeKind Kind); + PointerEscapeKind Kind, + bool IsConst = false); /// \brief Run checkers for handling assumptions on symbolic values. ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, @@ -442,7 +444,8 @@ public: typedef CheckerFn<ProgramStateRef (ProgramStateRef, const InvalidatedSymbols &Escaped, const CallEvent *Call, - PointerEscapeKind Kind)> + PointerEscapeKind Kind, + bool IsConst)> CheckPointerEscapeFunc; typedef CheckerFn<ProgramStateRef (ProgramStateRef, @@ -487,6 +490,8 @@ public: void _registerForPointerEscape(CheckPointerEscapeFunc checkfn); + void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn); + void _registerForEvalAssume(EvalAssumeFunc checkfn); void _registerForEvalCall(EvalCallFunc checkfn); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 3507533a0b..42c0c0488e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -467,12 +467,14 @@ protected: SVal Loc, SVal Val); /// Call PointerEscape callback when a value escapes as a result of /// region invalidation. - ProgramStateRef processPointerEscapedOnInvalidateRegions( + /// \param[in] IsConst Specifies that the pointer is const. + ProgramStateRef notifyCheckersOfPointerEscape( ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, - const CallEvent *Call); + const CallEvent *Call, + bool IsConst); public: // FIXME: 'tag' should be removed, and a LocationContext should be used diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index 8318fe0c26..9ae24c446e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -187,6 +187,8 @@ public: /// accessible. Pass \c NULL if this information will not be used. /// \param[in] Call The call expression which will be used to determine which /// globals should get invalidated. + /// \param[in,out] ConstIS A set to fill with any symbols corresponding to + /// the ConstRegions. /// \param[in,out] Invalidated A vector to fill with any regions being /// invalidated. This should include any regions explicitly invalidated /// even if they do not currently have bindings. Pass \c NULL if this @@ -198,6 +200,7 @@ public: InvalidatedSymbols &IS, const CallEvent *Call, ArrayRef<const MemRegion *> ConstRegions, + InvalidatedSymbols &ConstIS, InvalidatedRegions *Invalidated) = 0; /// enterStackFrame - Let the StoreManager to do something when execution diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index 0e9f25375d..4578f6f323 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -120,11 +120,12 @@ public: processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0; virtual ProgramStateRef - processPointerEscapedOnInvalidateRegions(ProgramStateRef State, + notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, - const CallEvent *Call) = 0; + const CallEvent *Call, + bool IsConst = false) = 0; /// printState - Called by ProgramStateManager to print checker-specific data. virtual void printState(raw_ostream &Out, ProgramStateRef State, |