diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-02 19:27:46 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-02 19:27:46 +0000 |
commit | 55037cdc2e29b70df2fd1ca0ba9d4c36da1049e8 (patch) | |
tree | 14c6b2358c028d1b9a934966c63a99396413c292 /lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp | |
parent | 4531b7d64e1ed03a925ffdcfb4aa065f2721afb8 (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.cpp | 49 |
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(); |