diff --git a/lib/Checker/DereferenceChecker.cpp b/lib/Checker/DereferenceChecker.cpp index af74c79558d59dcf0813f1bfe2db06258c3fd7a5..50392b28cd2017cb35e47aed4c27c667423e43dd 100644 --- a/lib/Checker/DereferenceChecker.cpp +++ b/lib/Checker/DereferenceChecker.cpp @@ -123,6 +123,19 @@ void DereferenceChecker::VisitLocation(CheckerContext &C, const Stmt *S, } break; } + case Stmt::ObjCIvarRefExprClass: { + const ObjCIvarRefExpr *IV = cast<ObjCIvarRefExpr>(S); + if (const DeclRefExpr *DR = + dyn_cast<DeclRefExpr>(IV->getBase()->IgnoreParenCasts())) { + if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { + llvm::raw_svector_ostream os(buf); + os << "Instance variable access (via '" << VD->getName() + << "') results in a null pointer dereference"; + } + } + Ranges.push_back(IV->getSourceRange()); + break; + } default: break; } diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 09f397041fb22be1d612902a8b9e17cfc757828b..a44eb0c18d33f6ad66d0aefd228ebd791be9fd97 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1110,3 +1110,22 @@ void rdar6351970_c() { @synchronized(x) {} // expected-warning{{Uninitialized value used as mutex for @synchronized}} } +// <rdar://problem/6352035> rule request: direct structure member access null pointer dereference +@interface RDar6352035 { + int c; +} +- (void)foo; +- (void)bar; +@end + +@implementation RDar6352035 +- (void)foo { + RDar6352035 *friend = 0; + friend->c = 7; // expected-warning{{Instance variable access (via 'friend') results in a null pointer dereference}} +} +- (void)bar { + self = 0; + c = 7; // expected-warning{{Instance variable access (via 'self') results in a null pointer dereference}} +} +@end +