// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -verify %s

#define nil 0
#define BOOL int

#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
#define NS_ASSUME_NONNULL_END   _Pragma("clang assume_nonnull end")

typedef struct _NSZone NSZone;

@protocol NSObject
+ (id)alloc;
- (id)init;
@end

NS_ASSUME_NONNULL_BEGIN
@protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;

@end

@protocol NSMutableCopying
- (id)mutableCopyWithZone:(nullable NSZone *)zone;
@end
NS_ASSUME_NONNULL_END

__attribute__((objc_root_class))
@interface
NSObject<NSObject>
@end

@interface NSString : NSObject<NSCopying>
- (BOOL)isEqualToString : (NSString *_Nonnull)aString;
- (NSString *)stringByAppendingString:(NSString *_Nonnull)aString;
@end

@interface TestObject : NSObject
- (int *_Nonnull)returnsNonnull;
- (int *_Nullable)returnsNullable;
- (int *)returnsUnspecified;
- (void)takesNonnull:(int *_Nonnull)p;
- (void)takesNullable:(int *_Nullable)p;
- (void)takesUnspecified:(int *)p;
@property(readonly, strong) NSString *stuff;
@end

TestObject * getUnspecifiedTestObject();
TestObject *_Nonnull getNonnullTestObject();
TestObject *_Nullable getNullableTestObject();

int getRandom();

typedef struct Dummy { int val; } Dummy;

void takesNullable(Dummy *_Nullable);
void takesNonnull(Dummy *_Nonnull);
void takesUnspecified(Dummy *);

Dummy *_Nullable returnsNullable();
Dummy *_Nonnull returnsNonnull();
Dummy *returnsUnspecified();
int *_Nullable returnsNullableInt();

template <typename T> T *eraseNullab(T *p) { return p; }

void takesAttrNonnull(Dummy *p) __attribute((nonnull(1)));

void testBasicRules() {
  Dummy *p = returnsNullable();
  int *ptr = returnsNullableInt();
  // Make every dereference a different path to avoid sinks after errors.
  switch (getRandom()) {
  case 0: {
    Dummy &r = *p; // expected-warning {{Nullable pointer is dereferenced}}
  } break;
  case 1: {
    int b = p->val; // expected-warning {{Nullable pointer is dereferenced}}
  } break;
  case 2: {
    int stuff = *ptr; // expected-warning {{Nullable pointer is dereferenced}}
  } break;
  case 3:
    takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
    break;
  case 4: {
    Dummy d;
    takesNullable(&d);
    Dummy dd(d);
    break;
  }
  case 5: takesAttrNonnull(p); break; // expected-warning {{Nullable pointer is passed to}}
  default: { Dummy d = *p; } break; // expected-warning {{Nullable pointer is dereferenced}}
  }
  if (p) {
    takesNonnull(p);
    if (getRandom()) {
      Dummy &r = *p;
    } else {
      int b = p->val;
    }
  }
  Dummy *q = 0;
  if (getRandom()) {
    takesNullable(q);
    takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
  }
  Dummy a;
  Dummy *_Nonnull nonnull = &a;
  nonnull = q; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}}
  q = &a;
  takesNullable(q);
  takesNonnull(q);
}

void testMultiParamChecking(Dummy *_Nonnull a, Dummy *_Nullable b,
                            Dummy *_Nonnull c);

void testArgumentTracking(Dummy *_Nonnull nonnull, Dummy *_Nullable nullable) {
  Dummy *p = nullable;
  Dummy *q = nonnull;
  switch(getRandom()) {
  case 1: nonnull = p; break; // expected-warning {{Nullable pointer is assigned to a pointer which is expected to have non-null value}}
  case 2: p = 0; break;
  case 3: q = p; break;
  case 4: testMultiParamChecking(nonnull, nullable, nonnull); break;
  case 5: testMultiParamChecking(nonnull, nonnull, nonnull); break;
  case 6: testMultiParamChecking(nonnull, nullable, nullable); break; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 3rd parameter}}
  case 7: testMultiParamChecking(nullable, nullable, nonnull); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
  case 8: testMultiParamChecking(nullable, nullable, nullable); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
  case 9: testMultiParamChecking((Dummy *_Nonnull)0, nullable, nonnull); break;
  }
}

Dummy *_Nonnull testNullableReturn(Dummy *_Nullable a) {
  Dummy *p = a;
  return p; // expected-warning {{Nullable pointer is returned from a function that is expected to return a non-null value}}
}

Dummy *_Nonnull testNullReturn() {
  Dummy *p = 0;
  return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
}

void testObjCMessageResultNullability() {
  // The expected result: the most nullable of self and method return type.
  TestObject *o = getUnspecifiedTestObject();
  int *shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNonnull];
  switch (getRandom()) {
  case 0:
    // The core analyzer assumes that the receiver is non-null after a message
    // send. This is to avoid some false positives, and increase performance
    // but it also reduces the coverage and makes this checker unable to reason
    // about the nullness of the receiver. 
    [o takesNonnull:shouldBeNullable]; // No warning expected.
    break;
  case 1:
    shouldBeNullable =
        [eraseNullab(getNullableTestObject()) returnsUnspecified];
    [o takesNonnull:shouldBeNullable]; // No warning expected.
    break;
  case 3:
    shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable];
    [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
    break;
  case 4:
    shouldBeNullable = [eraseNullab(getNonnullTestObject()) returnsNullable];
    [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
    break;
  case 5:
    shouldBeNullable =
        [eraseNullab(getUnspecifiedTestObject()) returnsNullable];
    [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
    break;
  case 6:
    shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable];
    [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
    break;
  case 7: {
    int *shouldBeNonnull = [eraseNullab(getNonnullTestObject()) returnsNonnull];
    [o takesNonnull:shouldBeNonnull];
  } break;
  }
}

Dummy * _Nonnull testDirectCastNullableToNonnull() {
  Dummy *p = returnsNullable();
  takesNonnull((Dummy * _Nonnull)p);  // no-warning
  return (Dummy * _Nonnull)p;         // no-warning
}

Dummy * _Nonnull testIndirectCastNullableToNonnull() {
  Dummy *p = (Dummy * _Nonnull)returnsNullable();
  takesNonnull(p);  // no-warning
  return p;         // no-warning
}

Dummy * _Nonnull testDirectCastNilToNonnull() {
  takesNonnull((Dummy * _Nonnull)0);  // no-warning
  return (Dummy * _Nonnull)0;         // no-warning
}

void testIndirectCastNilToNonnullAndPass() {
  Dummy *p = (Dummy * _Nonnull)0;
  // FIXME: Ideally the cast above would suppress this warning.
  takesNonnull(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
}

void testIndirectNilPassToNonnull() {
  Dummy *p = 0;
  takesNonnull(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
}

void testConditionalNilPassToNonnull(Dummy *p) {
  if (!p) {
    takesNonnull(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
  }
}

Dummy * _Nonnull testIndirectCastNilToNonnullAndReturn() {
  Dummy *p = (Dummy * _Nonnull)0;
  // FIXME: Ideally the cast above would suppress this warning.
  return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}}
}

void testInvalidPropagation() {
  Dummy *p = returnsUnspecified();
  takesNullable(p);
  takesNonnull(p);
}

void onlyReportFirstPreconditionViolationOnPath() {
  Dummy *p = returnsNullable();
  takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
  takesNonnull(p); // No warning.
  // The first warning was not a sink. The analysis expected to continue.
  int i = 0;
  i = 5 / i; // expected-warning {{Division by zero}}
  (void)i;
}

Dummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc(
    Dummy *_Nonnull p) {
  if (!p) {
    Dummy *ret =
        0; // avoid compiler warning (which is not generated by the analyzer)
    if (getRandom())
      return ret; // no warning
    else
      return p; // no warning
  } else {
    return p;
  }
}

Dummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) {
  if (!p) {
    Dummy *ret =
        0; // avoid compiler warning (which is not generated by the analyzer)
    if (getRandom())
      return ret; // no warning
    else
      return p; // no warning
  } else {
    return p;
  }
}

void testPreconditionViolationInInlinedFunction(Dummy *p) {
  doNotWarnWhenPreconditionIsViolated(p);
}

void inlinedNullable(Dummy *_Nullable p) {
  if (p) return;
}
void inlinedNonnull(Dummy *_Nonnull p) {
  if (p) return;
}
void inlinedUnspecified(Dummy *p) {
  if (p) return;
}

void testNilReturnWithBlock(Dummy *p) {
  p = 0;
  Dummy *_Nonnull (^myblock)(void) = ^Dummy *_Nonnull(void) {
    return p; // TODO: We should warn in blocks.
  };
  myblock();
}

Dummy *_Nonnull testDefensiveInlineChecks(Dummy * p) {
  switch (getRandom()) {
  case 1: inlinedNullable(p); break;
  case 2: inlinedNonnull(p); break;
  case 3: inlinedUnspecified(p); break;
  }
  if (getRandom())
    takesNonnull(p);  // no-warning

  if (getRandom()) {
    Dummy *_Nonnull varWithInitializer = p; // no-warning

     Dummy *_Nonnull var1WithInitializer = p,  // no-warning
           *_Nonnull var2WithInitializer = p;  // no-warning
  }

  if (getRandom()) {
    Dummy *_Nonnull varWithoutInitializer;
    varWithoutInitializer = p; // no-warning
  }

  return p;
}


@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 method that is expected to return a non-null value}}
}

- (TestObject * _Nonnull)testReturnsCastSuppressedNullableInNonnullIndirectly {
  TestObject *local = getNullableTestObject();
  return (TestObject * _Nonnull)local; // no-warning
}

- (TestObject * _Nonnull)testReturnsNullableInNonnullWhenPreconditionViolated:(TestObject * _Nonnull) p {
  TestObject *local = getNullableTestObject();
  if (!p) // Pre-condition violated here.
    return local; // no-warning
  else
    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;
  // False negative. Once we have more subtle suppression of defensive checks in
  // initializers we should warn here.
  return other;
}
@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
}

- (id _Nonnull)initWithNonnullReturnAndSelfCheckingIdiomV2; {
  // Another common return-checking idiom
  self = [super initWithNonnullReturnAndSelfCheckingIdiom];
  if (!self) {
    return nil; // no-warning
  }

  return self;
}
@end

@interface ClassWithCopyWithZone : NSObject<NSCopying,NSMutableCopying> {
  id i;
}

@end

@implementation ClassWithCopyWithZone
-(id)copyWithZone:(NSZone *)zone {
  ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init];
  if (!newInstance)
    return nil;

  newInstance->i = i;
  return newInstance;
}

-(id)mutableCopyWithZone:(NSZone *)zone {
  ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init];
  if (newInstance) {
    newInstance->i = i;
  }

  return newInstance;
}
@end
