aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-07-02 19:27:46 +0000
committerJordan Rose <jordan_rose@apple.com>2012-07-02 19:27:46 +0000
commit55037cdc2e29b70df2fd1ca0ba9d4c36da1049e8 (patch)
tree14c6b2358c028d1b9a934966c63a99396413c292 /lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
parent4531b7d64e1ed03a925ffdcfb4aa065f2721afb8 (diff)
[analyzer] Convert CallAndMessageChecker and ObjCSelfInitChecker to CallEvent.
Both of these got uglier rather than cleaner because we don't have preCall and postCall yet; properly wrapping a CallExpr in a CallEvent requires doing a bit of deconstruction on the callee. Even when we have preCall and postCall we may want to expose the current CallEvent to pre/postStmt<CallExpr>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159556 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp49
1 files changed, 39 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index 89340cc290..bb6ab6f2e3 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -39,6 +39,7 @@
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
@@ -73,8 +74,8 @@ public:
CheckerContext &C) const;
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
- void checkPreStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
- void checkPostStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
+ void checkPreStmt(const CallEvent &CE, CheckerContext &C) const;
+ void checkPostStmt(const CallEvent &CE, CheckerContext &C) const;
};
} // end anonymous namespace
@@ -208,7 +209,7 @@ void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
return;
}
- CallOrObjCMessage MsgWrapper(msg, C.getState(), C.getLocationContext());
+ ObjCMessageInvocation MsgWrapper(msg, C.getState(), C.getLocationContext());
checkPostStmt(MsgWrapper, C);
// We don't check for an invalid 'self' in an obj-c message expression to cut
@@ -259,23 +260,51 @@ void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S,
void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
CheckerContext &C) const {
- CallOrObjCMessage CEWrapper(CE, C.getState(), C.getLocationContext());
- checkPreStmt(CEWrapper, C);
+ // FIXME: This tree of switching can go away if/when we add a check::postCall.
+ const Expr *Callee = CE->getCallee()->IgnoreParens();
+ ProgramStateRef State = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal L = State->getSVal(Callee, LCtx);
+
+ if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
+ BlockCall Call(CE, State, LCtx);
+ checkPreStmt(Call, C);
+ } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
+ CXXMemberCall Call(me, State, LCtx);
+ checkPreStmt(Call, C);
+ } else {
+ FunctionCall Call(CE, State, LCtx);
+ checkPreStmt(Call, C);
+ }
}
void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
CheckerContext &C) const {
- CallOrObjCMessage CEWrapper(CE, C.getState(), C.getLocationContext());
- checkPostStmt(CEWrapper, C);
+ // FIXME: This tree of switching can go away if/when we add a check::postCall.
+ const Expr *Callee = CE->getCallee()->IgnoreParens();
+ ProgramStateRef State = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal L = State->getSVal(Callee, LCtx);
+
+ if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
+ BlockCall Call(CE, State, LCtx);
+ checkPostStmt(Call, C);
+ } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
+ CXXMemberCall Call(me, State, LCtx);
+ checkPostStmt(Call, C);
+ } else {
+ FunctionCall Call(CE, State, LCtx);
+ checkPostStmt(Call, C);
+ }
}
void ObjCSelfInitChecker::checkPreObjCMessage(ObjCMessage Msg,
CheckerContext &C) const {
- CallOrObjCMessage MsgWrapper(Msg, C.getState(), C.getLocationContext());
+ ObjCMessageInvocation MsgWrapper(Msg, C.getState(), C.getLocationContext());
checkPreStmt(MsgWrapper, C);
}
-void ObjCSelfInitChecker::checkPreStmt(const CallOrObjCMessage &CE,
+void ObjCSelfInitChecker::checkPreStmt(const CallEvent &CE,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
unsigned NumArgs = CE.getNumArgs();
@@ -298,7 +327,7 @@ void ObjCSelfInitChecker::checkPreStmt(const CallOrObjCMessage &CE,
}
}
-void ObjCSelfInitChecker::checkPostStmt(const CallOrObjCMessage &CE,
+void ObjCSelfInitChecker::checkPostStmt(const CallEvent &CE,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
unsigned NumArgs = CE.getNumArgs();