From: Devin Coughlin Date: Fri, 8 Apr 2016 19:59:16 +0000 (+0000) Subject: [analyzer] Teach trackNullOrUndefValue about calls to property accessors. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9535640b53d0c29ef6ae54db653c7bc7b123c7a7;p=clang [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@265839 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 859a2220e0..e0f014714f 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -908,6 +908,12 @@ static const Expr *peelOffOuterExpr(const Expr *Ex, return peelOffOuterExpr(EWC->getSubExpr(), N); if (const OpaqueValueExpr *OVE = dyn_cast(Ex)) return peelOffOuterExpr(OVE->getSourceExpr(), N); + if (auto *POE = dyn_cast(Ex)) { + auto *PropRef = dyn_cast(POE->getSyntacticForm()); + if (PropRef && PropRef->isMessagingGetter()) { + return peelOffOuterExpr(POE->getSemanticExpr(1), N); + } + } // Peel off the ternary operator. if (const ConditionalOperator *CO = dyn_cast(Ex)) { diff --git a/test/Analysis/inlining/false-positive-suppression.m b/test/Analysis/inlining/false-positive-suppression.m index 53ec138367..7be1cb8472 100644 --- a/test/Analysis/inlining/false-positive-suppression.m +++ b/test/Analysis/inlining/false-positive-suppression.m @@ -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 +}