From ebaa56bb263b56ee47d3492d7e32fe1db639b155 Mon Sep 17 00:00:00 2001 From: Devin Coughlin Date: Fri, 8 Apr 2016 19:59:16 +0000 Subject: [PATCH] [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 --- .../StaticAnalyzer/Core/BugReporterVisitors.cpp | 6 ++++ .../Analysis/inlining/false-positive-suppression.m | 36 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 859a222..e0f0147 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/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/clang/test/Analysis/inlining/false-positive-suppression.m b/clang/test/Analysis/inlining/false-positive-suppression.m index 53ec138..7be1cb8 100644 --- a/clang/test/Analysis/inlining/false-positive-suppression.m +++ b/clang/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 +} -- 2.7.4