[analyzer] Teach trackNullOrUndefValue about calls to property accessors.
authorDevin Coughlin <dcoughlin@apple.com>
Fri, 8 Apr 2016 19:59:16 +0000 (19:59 +0000)
committerDevin Coughlin <dcoughlin@apple.com>
Fri, 8 Apr 2016 19:59:16 +0000 (19:59 +0000)
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

clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
clang/test/Analysis/inlining/false-positive-suppression.m

index 859a222..e0f0147 100644 (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)) {
index 53ec138..7be1cb8 100644 (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
+}