// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s

typedef signed char BOOL;
typedef struct objc_class *Class;
typedef struct objc_object {
  Class isa;
} *id;
@protocol NSObject  - (BOOL)isEqual:(id)object; @end
@interface NSObject <NSObject> {}
+(id)alloc;
+(id)new;
-(id)init;
-(id)autorelease;
-(id)copy;
- (Class)class;
-(id)retain;
@end

// Check that inline defensive checks is triggered for null expressions
// within CompoundLiteralExpr.
typedef union {
  struct dispatch_object_s *_do;
  struct dispatch_source_s *_ds;
} dispatch_object_t __attribute__((__transparent_union__));
typedef struct dispatch_source_s *dispatch_source_t;

extern __attribute__((visibility("default"))) __attribute__((__nonnull__)) __attribute__((__nothrow__))
void
dispatch_resume(dispatch_object_t object);

@interface AppDelegate : NSObject {
@protected
	dispatch_source_t p;
}
@end
@implementation AppDelegate
- (void)updateDeleteTimer {
	if (p != ((void*)0))
		;
}
- (void)createAndStartDeleteTimer {
  [self updateDeleteTimer];
  dispatch_resume(p); // no warning
}
@end

// Test nil receiver suppression.
// We only suppress on nil receiver if the nil value is directly causing the bug.
@interface Foo {
@public
  int x;
}
- (Foo *)getFooPtr;
@end

Foo *retNil() {
  return 0;
}

Foo *retInputOrNil(Foo *p) {
  if (p)
    return p;
  return 0;
}

void idc(Foo *p) {
  if (p)
    ;
}

int testNilReceiver(Foo* fPtr) {
  if (fPtr)
    ;
  // On a path where fPtr is nil, mem should be nil.
  Foo *mem = [fPtr getFooPtr];
  return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}}
}

int suppressNilReceiverRetNullCond(Foo* fPtr) {
  unsigned zero = 0;
  fPtr = retInputOrNil(fPtr);
  // On a path where fPtr is nzil, mem should be nil.
  Foo *mem = [fPtr getFooPtr];
  return mem->x;
}

int suppressNilReceiverRetNullCondCast(id fPtr) {
  unsigned zero = 0;
  fPtr = retInputOrNil(fPtr);
  // On a path where fPtr is nzil, mem should be nil.
  Foo *mem = ((id)([(Foo*)(fPtr) getFooPtr]));
  return mem->x;
}

int dontSuppressNilReceiverRetNullCond(Foo* fPtr) {
  unsigned zero = 0;
  fPtr = retInputOrNil(fPtr);
  // On a path where fPtr is nil, mem should be nil.
  // The warning is not suppressed because the receiver being nil is not
  // directly related to the value that triggers the warning.
  Foo *mem = [fPtr getFooPtr];
  if (!mem)
    return 5/zero; // expected-warning {{Division by zero}}
  return 0;
}

int dontSuppressNilReceiverRetNull(Foo* fPtr) {
  unsigned zero = 0;
  fPtr = retNil();
  // On a path where fPtr is nil, mem should be nil.
  // The warning is not suppressed because the receiver being nil is not
  // directly related to the value that triggers the warning.
  Foo *mem = [fPtr getFooPtr];
  if (!mem)
    return 5/zero; // expected-warning {{Division by zero}}
  return 0;
}

int dontSuppressNilReceiverIDC(Foo* fPtr) {
  unsigned zero = 0;
  idc(fPtr);
  // On a path where fPtr is nil, mem should be nil.
  // The warning is not suppressed because the receiver being nil is not
  // directly related to the value that triggers the warning.
  Foo *mem = [fPtr getFooPtr];
  if (!mem)
    return 5/zero; // expected-warning {{Division by zero}}
  return 0;
}
