aboutsummaryrefslogtreecommitdiff
path: root/include/clang/StaticAnalyzer
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-03-28 23:15:29 +0000
committerAnna Zaks <ganna@apple.com>2013-03-28 23:15:29 +0000
commit41988f331a74a72cf243a2a68ffb56418e9a174e (patch)
treeab722ed0a8b1c5b6686d45cf7765b0e85564d7a8 /include/clang/StaticAnalyzer
parentaabb4c5eacca6d78ef778f33ec5cd4c755d71a39 (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')
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h40
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h5
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,