diff --git a/clang/include/clang/StaticAnalyzer/PathSensitive/ObjCMessage.h b/clang/include/clang/StaticAnalyzer/PathSensitive/ObjCMessage.h index 4e5ce09d7ae1..1af4e0290cf7 100644 --- a/clang/include/clang/StaticAnalyzer/PathSensitive/ObjCMessage.h +++ b/clang/include/clang/StaticAnalyzer/PathSensitive/ObjCMessage.h @@ -78,7 +78,10 @@ public: assert(isValid() && "This ObjCMessage is uninitialized!"); if (const ObjCMessageExpr *msgE = dyn_cast(MsgOrPropE)) return msgE->getInstanceReceiver(); - return cast(MsgOrPropE)->getBase(); + const ObjCPropertyRefExpr *propE = cast(MsgOrPropE); + if (propE->isObjectReceiver()) + return propE->getBase(); + return 0; } bool isInstanceMessage() const { diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp index 8ad094b1d3b8..79d2a2b2fc07 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp @@ -2073,12 +2073,13 @@ void ExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred, void ExprEngine::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - - // Visit the base expression, which is needed for computing the lvalue - // of the ivar. ExplodedNodeSet dstBase; - const Expr *baseExpr = Ex->getBase(); - Visit(baseExpr, Pred, dstBase); + + // Visit the receiver (if any). + if (Ex->isObjectReceiver()) + Visit(Ex->getBase(), Pred, dstBase); + else + dstBase = Pred; ExplodedNodeSet dstPropRef; @@ -2087,7 +2088,6 @@ void ExprEngine::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Ex, I!=E; ++I) { ExplodedNode *nodeBase = *I; const GRState *state = GetState(nodeBase); - SVal baseVal = state->getSVal(baseExpr); MakeNode(dstPropRef, Ex, *I, state->BindExpr(Ex, loc::ObjCPropRef(Ex))); } diff --git a/clang/test/Analysis/properties.m b/clang/test/Analysis/properties.m index b0325a1ce7cb..ce8faf52736a 100644 --- a/clang/test/Analysis/properties.m +++ b/clang/test/Analysis/properties.m @@ -133,3 +133,13 @@ void rdar6611873() { p.name = [[NSString string] retain]; // expected-warning {{leak}} p.name = [[NSString alloc] init]; // expected-warning {{leak}} } + +@interface SubPerson : Person +-(NSString *)foo; +@end + +@implementation SubPerson +-(NSString *)foo { + return super.name; +} +@end