[analyzer] Teach trackNullOrUndefValue() about class property accessors.

Teach trackNullOrUndefValue() how to properly look through PseudoObjectExprs
to find the underlying semantic method call for property getters. This fixes a
crash when looking through class property getters that I introduced in r265839.

rdar://problem/26796666

llvm-svn: 273340
This commit is contained in:
Devin Coughlin 2016-06-22 00:20:00 +00:00
parent 644d9d3a44
commit 803ee03117
2 changed files with 32 additions and 1 deletions

View File

@ -914,7 +914,10 @@ static const Expr *peelOffOuterExpr(const Expr *Ex,
if (auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) { if (auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
if (PropRef && PropRef->isMessagingGetter()) { if (PropRef && PropRef->isMessagingGetter()) {
return peelOffOuterExpr(POE->getSemanticExpr(1), N); const Expr *GetterMessageSend =
POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
assert(isa<ObjCMessageExpr>(GetterMessageSend));
return peelOffOuterExpr(GetterMessageSend, N);
} }
} }

View File

@ -49,6 +49,12 @@ __attribute__((objc_root_class))
@end @end
@interface SubOfSomeClass : SomeClass
@end
@implementation SubOfSomeClass
@end
@implementation SomeClass @implementation SomeClass
-(int *)methodReturningNull { -(int *)methodReturningNull {
return 0; return 0;
@ -57,6 +63,10 @@ __attribute__((objc_root_class))
-(int *)propertyReturningNull { -(int *)propertyReturningNull {
return 0; return 0;
} }
+(int *)classPropertyReturningNull {
return 0;
}
@end @end
void testMethodReturningNull(SomeClass *sc) { void testMethodReturningNull(SomeClass *sc) {
@ -75,6 +85,24 @@ void testPropertyReturningNull(SomeClass *sc) {
#endif #endif
} }
@implementation SubOfSomeClass (ForTestOfSuperProperty)
-(void)testSuperPropertyReturningNull {
int *result = super.propertyReturningNull;
*result = 1;
#ifndef SUPPRESSED
// expected-warning@-2 {{Dereference of null pointer}}
#endif
}
@end
void testClassPropertyReturningNull() {
int *result = SomeClass.classPropertyReturningNull;
*result = 1;
#ifndef SUPPRESSED
// expected-warning@-2 {{Dereference of null pointer}}
#endif
}
void testSynthesizedPropertyReturningNull(SomeClass *sc) { void testSynthesizedPropertyReturningNull(SomeClass *sc) {
if (sc.synthesizedProperty) if (sc.synthesizedProperty)
return; return;