]> granicus.if.org Git - clang/commitdiff
[analyzer] Teach trackNullOrUndefValue() about class property accessors.
authorDevin Coughlin <dcoughlin@apple.com>
Wed, 22 Jun 2016 00:20:00 +0000 (00:20 +0000)
committerDevin Coughlin <dcoughlin@apple.com>
Wed, 22 Jun 2016 00:20:00 +0000 (00:20 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273340 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 657d33fa7a39ec83b4812a1cf2d5b8632449e1a1..85a0b4789696b8515bdf87fae5a1bf0d655ea53d 100644 (file)
@@ -914,7 +914,10 @@ static const Expr *peelOffOuterExpr(const Expr *Ex,
   if (auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
     auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
     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);
     }
   }
 
index d9678206c7c5781710b3fb489a5b0b2ca55ed7e4..1a5ff662c18ea7c9f64038a2e63b619f3c607167 100644 (file)
@@ -49,6 +49,12 @@ __attribute__((objc_root_class))
 
 @end
 
+@interface SubOfSomeClass : SomeClass
+@end
+
+@implementation SubOfSomeClass
+@end
+
 @implementation SomeClass
 -(int *)methodReturningNull {
   return 0;
@@ -57,6 +63,10 @@ __attribute__((objc_root_class))
 -(int *)propertyReturningNull {
   return 0;
 }
+
++(int *)classPropertyReturningNull {
+  return 0;
+}
 @end
 
 void testMethodReturningNull(SomeClass *sc) {
@@ -75,6 +85,24 @@ void testPropertyReturningNull(SomeClass *sc) {
 #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) {
   if (sc.synthesizedProperty)
     return;