aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-02-18 20:53:30 +0000
committerTed Kremenek <kremenek@apple.com>2012-02-18 20:53:30 +0000
commitb673a41c92aa276f2e37164d0747be1cfb0c402b (patch)
tree8aeddce7a22083ef77d891d995cfdf3c986737e3 /lib/StaticAnalyzer/Core/ExprEngine.cpp
parentb8197bcdd7453ef85d282b0e5141761f4bd83b64 (diff)
Adopt ExprEngine and checkers to ObjC property refactoring. Everything was working, but now diagnostics are aware of message expressions implied by uses of properties. Fixes <rdar://problem/9241180>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150888 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp34
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 6f588c5ae1..34ad23a429 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -808,11 +808,33 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.addNodes(Dst);
break;
- case Stmt::ObjCMessageExprClass:
+ case Stmt::ObjCMessageExprClass: {
Bldr.takeNodes(Pred);
- VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
+ // Is this a property access?
+ const ParentMap &PM = Pred->getLocationContext()->getParentMap();
+ const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(S);
+ bool evaluated = false;
+
+ if (const PseudoObjectExpr *PO =
+ dyn_cast_or_null<PseudoObjectExpr>(PM.getParent(S))) {
+ const Expr *syntactic = PO->getSyntacticForm();
+ if (const ObjCPropertyRefExpr *PR =
+ dyn_cast<ObjCPropertyRefExpr>(syntactic)) {
+ bool isSetter = ME->getNumArgs() > 0;
+ VisitObjCMessage(ObjCMessage(ME, PR, isSetter), Pred, Dst);
+ evaluated = true;
+ }
+ else if (isa<BinaryOperator>(syntactic)) {
+ VisitObjCMessage(ObjCMessage(ME, 0, true), Pred, Dst);
+ }
+ }
+
+ if (!evaluated)
+ VisitObjCMessage(ME, Pred, Dst);
+
Bldr.addNodes(Dst);
break;
+ }
case Stmt::ObjCAtThrowStmtClass: {
// FIXME: This is not complete. We basically treat @throw as
@@ -1439,9 +1461,7 @@ void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
const Expr *StoreE = AssignE ? AssignE : LocationE;
if (isa<loc::ObjCPropRef>(location)) {
- loc::ObjCPropRef prop = cast<loc::ObjCPropRef>(location);
- return VisitObjCMessage(ObjCPropertySetter(prop.getPropRefExpr(),
- StoreE, Val), Pred, Dst);
+ assert(false);
}
// Evaluate the location (checks for bad dereferences).
@@ -1466,9 +1486,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *Ex,
assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
if (isa<loc::ObjCPropRef>(location)) {
- loc::ObjCPropRef prop = cast<loc::ObjCPropRef>(location);
- return VisitObjCMessage(ObjCPropertyGetter(prop.getPropRefExpr(), Ex),
- Pred, Dst);
+ assert(false);
}
// Are we loading from a region? This actually results in two loads; one