forked from OSchip/llvm-project
[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:
parent
644d9d3a44
commit
803ee03117
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue