[analyzer] Suppress nullability warning for defensive super initializer idiom.

A common idiom in Objective-C initializers is for a defensive nil-check on the
result of a call to a super initializer:
  if (self = [super init]) {
     ...
  }
  return self;

To avoid warning on this idiom, the nullability checker now suppress diagnostics
for returns of nil on syntactic 'return self' even in initializers with non-null
return types.

llvm-svn: 258461
diff --git a/clang/test/Analysis/nullability.mm b/clang/test/Analysis/nullability.mm
index aa909fb..b119e63 100644
--- a/clang/test/Analysis/nullability.mm
+++ b/clang/test/Analysis/nullability.mm
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fobjc-arc -analyze -analyzer-checker=core,nullability -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability -verify %s
 
 #define nil 0
 #define BOOL int
@@ -279,10 +280,21 @@
   return p;
 }
 
-@interface SomeClass : NSObject
+
+@interface SomeClass : NSObject {
+  int instanceVar;
+}
 @end
 
 @implementation SomeClass (MethodReturn)
+- (id)initWithSomething:(int)i {
+  if (self = [super init]) {
+    instanceVar = i;
+  }
+
+  return self;
+}
+
 - (TestObject * _Nonnull)testReturnsNullableInNonnullIndirectly {
   TestObject *local = getNullableTestObject();
   return local; // expected-warning {{Nullable pointer is returned from a function that is expected to return a non-null value}}
@@ -301,3 +313,41 @@
     return p; // no-warning
 }
 @end
+
+@interface ClassWithInitializers : NSObject
+@end
+
+@implementation ClassWithInitializers
+- (instancetype _Nonnull)initWithNonnullReturnAndSelfCheckingIdiom {
+  // This defensive check is a common-enough idiom that we filter don't want
+  // to issue a diagnostic for it,
+  if (self = [super init]) {
+  }
+
+  return self; // no-warning
+}
+
+- (instancetype _Nonnull)initWithNonnullReturnAndNilReturnViaLocal {
+  self = [super init];
+  // This leaks, but we're not checking for that here.
+
+  ClassWithInitializers *other = nil;
+  // Still warn when when not returning via self.
+  return other; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
+}
+@end
+
+@interface SubClassWithInitializers : ClassWithInitializers
+@end
+
+@implementation SubClassWithInitializers
+// Note: Because this is overridding
+// -[ClassWithInitializers initWithNonnullReturnAndSelfCheckingIdiom],
+// the return type of this method becomes implicitly id _Nonnull.
+- (id)initWithNonnullReturnAndSelfCheckingIdiom {
+  if (self = [super initWithNonnullReturnAndSelfCheckingIdiom]) {
+  }
+
+  return self; // no-warning
+}
+@end