[analyzer] Teach trackNullOrUndefValue about calls to property accessors.

Teach trackNullOrUndefValue() how to look through PseudoObjectExprs to find
the underlying method call for property getters. This makes over-suppression
of 'return nil' in getters consistent with the similar over-suppression for
method and function calls.

rdar://problem/24437252

llvm-svn: 265839
This commit is contained in:
Devin Coughlin 2016-04-08 19:59:16 +00:00
parent fe1bc708b5
commit ebaa56bb26
2 changed files with 42 additions and 0 deletions

View File

@ -908,6 +908,12 @@ static const Expr *peelOffOuterExpr(const Expr *Ex,
return peelOffOuterExpr(EWC->getSubExpr(), N);
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
return peelOffOuterExpr(OVE->getSourceExpr(), N);
if (auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
if (PropRef && PropRef->isMessagingGetter()) {
return peelOffOuterExpr(POE->getSemanticExpr(1), N);
}
}
// Peel off the ternary operator.
if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {

View File

@ -36,3 +36,39 @@ void testNilReceiver(int coin) {
else
testNilReceiverHelperB([[x getObject] getPtr]);
}
// FALSE NEGATIVES (over-suppression)
__attribute__((objc_root_class))
@interface SomeClass
-(int *)methodReturningNull;
@property(readonly) int *propertyReturningNull;
@end
@implementation SomeClass
-(int *)methodReturningNull {
return 0;
}
-(int *)propertyReturningNull {
return 0;
}
@end
void testMethodReturningNull(SomeClass *sc) {
int *result = [sc methodReturningNull];
*result = 1;
#ifndef SUPPRESSED
// expected-warning@-2 {{Dereference of null pointer}}
#endif
}
void testPropertyReturningNull(SomeClass *sc) {
int *result = sc.propertyReturningNull;
*result = 1;
#ifndef SUPPRESSED
// expected-warning@-2 {{Dereference of null pointer}}
#endif
}