// RUN: %clang_analyze_cc1 -std=c++14 -fblocks -analyze -analyzer-output=text\
// RUN:   -analyzer-checker=core,osx,debug.ExprInspection -verify %s

#include "os_object_base.h"
#include "os_smart_ptr.h"

void clang_analyzer_eval(bool);

struct OSIterator : public OSObject {
  static const OSMetaClass * const metaClass;
};

struct OSArray : public OSObject {
  unsigned int getCount();

  OSIterator * getIterator();

  OSObject *identity() override;

  virtual OSObject *generateObject(OSObject *input);

  virtual void consumeReference(OS_CONSUME OSArray *other);

  void putIntoArray(OSArray *array) OS_CONSUMES_THIS;

  template <typename T>
  void putIntoT(T *owner) OS_CONSUMES_THIS;

  static OSArray *generateArrayHasCode() {
    return new OSArray;
  }

  static OSArray *withCapacity(unsigned int capacity);
  static void consumeArray(OS_CONSUME OSArray * array);

  static OSArray* consumeArrayHasCode(OS_CONSUME OSArray * array) { // expected-note{{Parameter 'array' starts at +1, as it is marked as consuming}}
    return nullptr; // expected-warning{{Potential leak of an object of type 'OSArray'}}
// expected-note@-1{{Object leaked: allocated object of type 'OSArray' is not referenced later in this execution path and has a retain count of +1}}
  }


  static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter();
  static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate();

  static const OSMetaClass * const metaClass;
};

struct MyArray : public OSArray {
  void consumeReference(OSArray *other) override;

  OSObject *identity() override;

  OSObject *generateObject(OSObject *input) override;
};

struct OtherStruct {
  static void doNothingToArray(OSArray *array);
  OtherStruct(OSArray *arr);
};

bool test_meta_cast_no_leak(OSMetaClassBase *arg) {
  return arg && arg->metaCast("blah") != nullptr;
}

static void consumedMismatch(OS_CONSUME OSObject *a,
                             OSObject *b) { // expected-note{{Parameter 'b' starts at +0}}
  a->release();
  b->retain(); // expected-note{{Reference count incremented. The object now has a +1 retain count}}
} // expected-warning{{Potential leak of an object of type 'OSObject'}}
// expected-note@-1{{Object leaked: allocated object of type 'OSObject' is not referenced later in this execution path and has a retain count of +1}}

void escape(void *);
void escape_with_source(void *p) {}
bool coin();

typedef int kern_return_t;
typedef kern_return_t IOReturn;
typedef kern_return_t OSReturn;
#define kOSReturnSuccess  0
#define kIOReturnSuccess 0

bool write_into_out_param_on_success(OS_RETURNS_RETAINED OSObject **obj);

void use_out_param() {
  OSObject *obj;
  if (write_into_out_param_on_success(&obj)) {
    obj->release();
  }
}

void use_out_param_leak() {
  OSObject *obj;
  write_into_out_param_on_success(&obj); // expected-note-re{{Call to function 'write_into_out_param_on_success' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'obj' (assuming the call returns non-zero){{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj'}}
 // expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}

bool write_into_out_param_on_failure(OS_RETURNS_RETAINED_ON_ZERO OSObject **obj);

void use_out_param_leak2() {
  OSObject *obj;
  write_into_out_param_on_failure(&obj); // expected-note-re{{Call to function 'write_into_out_param_on_failure' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'obj' (assuming the call returns zero){{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj'}}
 // expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}

void use_out_param_on_failure() {
  OSObject *obj;
  if (!write_into_out_param_on_failure(&obj)) {
    obj->release();
  }
}

IOReturn write_into_out_param_on_nonzero(OS_RETURNS_RETAINED_ON_NONZERO OSObject **obj);

void use_out_param_on_nonzero() {
  OSObject *obj;
  if (write_into_out_param_on_nonzero(&obj) != kIOReturnSuccess) {
    obj->release();
  }
}

bool write_into_two_out_params(OS_RETURNS_RETAINED OSObject **a,
                               OS_RETURNS_RETAINED OSObject **b);

void use_write_into_two_out_params() {
  OSObject *obj1;
  OSObject *obj2;
  if (write_into_two_out_params(&obj1, &obj2)) {
    obj1->release();
    obj2->release();
  }
}

void use_write_two_out_params_leak() {
  OSObject *obj1;
  OSObject *obj2;
  write_into_two_out_params(&obj1, &obj2); // expected-note-re{{Call to function 'write_into_two_out_params' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'a' (assuming the call returns non-zero){{$}}}}
                                           // expected-note-re@-1{{Call to function 'write_into_two_out_params' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'b' (assuming the call returns non-zero){{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj1'}}
  // expected-warning@-1{{Potential leak of an object stored into 'obj2'}}
  // expected-note@-2{{Object leaked: object allocated and stored into 'obj1' is not referenced later in this execution path and has a retain count of +1}}
  // expected-note@-3{{Object leaked: object allocated and stored into 'obj2' is not referenced later in this execution path and has a retain count of +1}}

void always_write_into_two_out_params(OS_RETURNS_RETAINED OSObject **a,
                                      OS_RETURNS_RETAINED OSObject **b);

void use_always_write_into_two_out_params() {
  OSObject *obj1;
  OSObject *obj2;
  always_write_into_two_out_params(&obj1, &obj2);
  obj1->release();
  obj2->release();
}

void use_always_write_into_two_out_params_leak() {
  OSObject *obj1;
  OSObject *obj2;
  always_write_into_two_out_params(&obj1, &obj2); // expected-note-re{{Call to function 'always_write_into_two_out_params' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'a'{{$}}}}
                                                  // expected-note-re@-1{{Call to function 'always_write_into_two_out_params' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'b'{{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj1'}}
  // expected-warning@-1{{Potential leak of an object stored into 'obj2'}}
  // expected-note@-2{{Object leaked: object allocated and stored into 'obj1' is not referenced later in this execution path and has a retain count of +1}}
  // expected-note@-3{{Object leaked: object allocated and stored into 'obj2' is not referenced later in this execution path and has a retain count of +1}}

char *write_into_out_param_on_nonnull(OS_RETURNS_RETAINED OSObject **obj);

void use_out_param_osreturn_on_nonnull() {
  OSObject *obj;
  if (write_into_out_param_on_nonnull(&obj)) {
    obj->release();
  }
}

void use_out_param_leak_osreturn_on_nonnull() {
  OSObject *obj;
  write_into_out_param_on_nonnull(&obj); // expected-note-re{{Call to function 'write_into_out_param_on_nonnull' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'obj' (assuming the call returns non-zero){{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj'}}
  // expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}

bool write_optional_out_param(OS_RETURNS_RETAINED OSObject **obj=nullptr);

void use_optional_out_param() {
  if (write_optional_out_param()) {};
}

OSReturn write_into_out_param_on_os_success(OS_RETURNS_RETAINED OSObject **obj);

void write_into_non_retained_out_param(OS_RETURNS_NOT_RETAINED OSObject **obj);

void use_write_into_non_retained_out_param() {
  OSObject *obj;
  write_into_non_retained_out_param(&obj);
}

void use_write_into_non_retained_out_param_uaf() {
  OSObject *obj;
  write_into_non_retained_out_param(&obj); // expected-note-re{{Call to function 'write_into_non_retained_out_param' writes an OSObject of type 'OSObject' with a +0 retain count into an out parameter 'obj'{{$}}}}
  obj->release(); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
                  // expected-note@-1{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
}

void always_write_into_out_param(OS_RETURNS_RETAINED OSObject **obj);

void pass_through_out_param(OSObject **obj) {
  always_write_into_out_param(obj);
}

void always_write_into_out_param_has_source(OS_RETURNS_RETAINED OSObject **obj) {
  *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
}

void use_always_write_into_out_param_has_source_leak() {
  OSObject *obj;
  always_write_into_out_param_has_source(&obj); // expected-note{{Calling 'always_write_into_out_param_has_source'}}
                                                // expected-note@-1{{Returning from 'always_write_into_out_param_has_source'}}
} // expected-warning{{Potential leak of an object stored into 'obj'}}
  // expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}

void use_void_out_param_osreturn() {
  OSObject *obj;
  always_write_into_out_param(&obj);
  obj->release();
}

void use_void_out_param_osreturn_leak() {
  OSObject *obj;
  always_write_into_out_param(&obj); // expected-note-re{{Call to function 'always_write_into_out_param' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'obj'{{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj'}}
  // expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}

void use_out_param_osreturn() {
  OSObject *obj;
  if (write_into_out_param_on_os_success(&obj) == kOSReturnSuccess) {
    obj->release();
  }
}

void use_out_param_leak_osreturn() {
  OSObject *obj;
  write_into_out_param_on_os_success(&obj); // expected-note-re{{Call to function 'write_into_out_param_on_os_success' writes an OSObject of type 'OSObject' with a +1 retain count into an out parameter 'obj' (assuming the call returns zero){{$}}}}
} // expected-warning{{Potential leak of an object stored into 'obj'}}
  // expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}

void cleanup(OSObject **obj);

void test_cleanup_escaping() {
  __attribute__((cleanup(cleanup))) OSObject *obj;
  always_write_into_out_param(&obj); // no-warning, the value has escaped.
}

struct StructWithField {
  OSObject *obj;

  void initViaOutParamCall() { // no warning on writing into fields
    always_write_into_out_param(&obj);
  }

};

bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
  if (coin()) { // expected-note{{Assuming the condition is false}}
                // expected-note@-1{{Taking false branch}}
    escape(obj);
    return true;
  }
  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function did not consume the reference}}
}

bool os_consume_violation(OS_CONSUME OSObject *obj) {
  if (coin()) { // expected-note{{Assuming the condition is false}}
                // expected-note@-1{{Taking false branch}}
    escape(obj);
    return true;
  }
  return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function did not consume the reference}}
}

void os_consume_ok(OS_CONSUME OSObject *obj) {
  escape(obj);
}

void use_os_consume_violation() {
  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
  os_consume_violation(obj); // expected-note{{Calling 'os_consume_violation'}}
                             // expected-note@-1{{Returning from 'os_consume_violation'}}
} // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
  // expected-warning@-1{{Potential leak of an object stored into 'obj'}}

void use_os_consume_violation_two_args() {
  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
  os_consume_violation_two_args(obj, coin()); // expected-note{{Calling 'os_consume_violation_two_args'}}
                             // expected-note@-1{{Returning from 'os_consume_violation_two_args'}}
} // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
  // expected-warning@-1{{Potential leak of an object stored into 'obj'}}

void use_os_consume_ok() {
  OSObject *obj = new OSObject;
  os_consume_ok(obj);
}

void test_escaping_into_voidstar() {
  OSObject *obj = new OSObject;
  escape(obj);
}

void test_escape_has_source() {
  OSObject *obj = new OSObject;
  if (obj)
    escape_with_source(obj);
  return;
}

void test_no_infinite_check_recursion(MyArray *arr) {
  OSObject *input = new OSObject;
  OSObject *o = arr->generateObject(input);
  o->release();
  input->release();
}


void check_param_attribute_propagation(MyArray *parent) {
  OSArray *arr = new OSArray;
  parent->consumeReference(arr);
}

unsigned int check_attribute_propagation(OSArray *arr) {
  OSObject *other = arr->identity();
  OSArray *casted = OSDynamicCast(OSArray, other);
  if (casted)
    return casted->getCount();
  return 0;
}

unsigned int check_attribute_indirect_propagation(MyArray *arr) {
  OSObject *other = arr->identity();
  OSArray *casted = OSDynamicCast(OSArray, other);
  if (casted)
    return casted->getCount();
  return 0;
}

void check_consumes_this(OSArray *owner) {
  OSArray *arr = new OSArray;
  arr->putIntoArray(owner);
}

void check_consumes_this_with_template(OSArray *owner) {
  OSArray *arr = new OSArray;
  arr->putIntoT(owner);
}

void check_free_no_error() {
  OSArray *arr = OSArray::withCapacity(10);
  arr->retain();
  arr->retain();
  arr->retain();
  arr->free();
}

void check_free_use_after_free() {
  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
  arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
  arr->free(); // expected-note{{Object released}}
  arr->retain(); // expected-warning{{Reference-counted object is used after it is released}}
                 // expected-note@-1{{Reference-counted object is used after it is released}}
}

unsigned int check_leak_explicit_new() {
  OSArray *arr = new OSArray; // expected-note{{Operator 'new' returns an OSObject of type 'OSArray' with a +1 retain count}}
  return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
                          // expected-warning@-1{{Potential leak of an object stored into 'arr'}}
}

unsigned int check_leak_factory() {
  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
  return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
                          // expected-warning@-1{{Potential leak of an object stored into 'arr'}}
}

void check_get_object() {
  OSObject::getObject();
}

void check_Get_object() {
  OSObject::GetObject();
}

void check_custom_iterator_rule(OSArray *arr) {
  OSIterator *it = arr->getIterator();
  it->release();
}

void check_iterator_leak(OSArray *arr) {
  arr->getIterator(); // expected-note{{Call to method 'OSArray::getIterator' returns an OSObject of type 'OSIterator' with a +1 retain count}}
} // expected-note{{Object leaked: allocated object of type 'OSIterator' is not referenced later}}
  // expected-warning@-1{{Potential leak of an object of type 'OSIterator}}'

void check_no_invalidation() {
  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
  OtherStruct::doNothingToArray(arr);
} // expected-warning{{Potential leak of an object stored into 'arr'}}
  // expected-note@-1{{Object leaked}}

void check_no_invalidation_other_struct() {
  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
  OtherStruct other(arr); // expected-warning{{Potential leak}}
                          // expected-note@-1{{Object leaked}}
}

struct ArrayOwner : public OSObject {
  OSArray *arr;
  ArrayOwner(OSArray *arr) : arr(arr) {}

  static ArrayOwner* create(OSArray *arr) {
    return new ArrayOwner(arr);
  }

  OSArray *getArray() {
    return arr;
  }

  OSArray *createArray() {
    return OSArray::withCapacity(10);
  }

  OSArray *createArraySourceUnknown();

  OSArray *getArraySourceUnknown();
};

OSArray *generateArray() {
  return OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
                                    // expected-note@-1{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
}

unsigned int check_leak_good_error_message() {
  unsigned int out;
  {
    OSArray *leaked = generateArray(); // expected-note{{Calling 'generateArray'}}
                                       // expected-note@-1{{Returning from 'generateArray'}}
    out = leaked->getCount(); // expected-warning{{Potential leak of an object stored into 'leaked'}}
                              // expected-note@-1{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
  }
  return out;
}

unsigned int check_leak_msg_temporary() {
  return generateArray()->getCount(); // expected-warning{{Potential leak of an object}}
                                      // expected-note@-1{{Calling 'generateArray'}}
                                      // expected-note@-2{{Returning from 'generateArray'}}
                                      // expected-note@-3{{Object leaked: allocated object of type 'OSArray' is not referenced later in this execution path and has a retain count of +1}}
}

void check_confusing_getters() {
  OSArray *arr = OSArray::withCapacity(10);

  ArrayOwner *AO = ArrayOwner::create(arr);
  AO->getArray();

  AO->release();
  arr->release();
}

void check_rc_consumed() {
  OSArray *arr = OSArray::withCapacity(10);
  OSArray::consumeArray(arr);
}

void check_rc_consume_temporary() {
  OSArray::consumeArray(OSArray::withCapacity(10));
}

void check_rc_getter() {
  OSArray *arr = OSArray::MaskedGetter();
  (void)arr;
}

void check_rc_create() {
  OSArray *arr = OSArray::getOoopsActuallyCreate();
  arr->release();
}


void check_dynamic_cast() {
  OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1));
  arr->release();
}

void check_required_cast() {
  OSArray *arr = OSRequiredCast(OSArray, OSObject::generateObject(1));
  arr->release(); // no-warning
}

void check_cast_behavior(OSObject *obj) {
  OSArray *arr1 = OSDynamicCast(OSArray, obj);
  clang_analyzer_eval(arr1 == obj); // expected-warning{{TRUE}}
                                    // expected-note@-1{{TRUE}}
                                    // expected-note@-2{{Assuming 'arr1' is not equal to 'obj'}}
                                    // expected-warning@-3{{FALSE}}
                                    // expected-note@-4   {{FALSE}}
  OSArray *arr2 = OSRequiredCast(OSArray, obj);
  clang_analyzer_eval(arr2 == obj); // expected-warning{{TRUE}}
                                    // expected-note@-1{{TRUE}}
}

unsigned int check_dynamic_cast_no_null_on_orig(OSObject *obj) {
  OSArray *arr = OSDynamicCast(OSArray, obj);
  if (arr) {
    return arr->getCount();
  } else {

    // The fact that dynamic cast has failed should not imply that
    // the input object was null.
    return obj->foo(); // no-warning
  }
}

void check_dynamic_cast_null_branch(OSObject *obj) {
  OSArray *arr1 = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject}}
  OSArray *arr = OSDynamicCast(OSArray, obj); // expected-note{{Assuming dynamic cast returns null due to type mismatch}}
  if (!arr) // expected-note{{'arr' is null}}
            // expected-note@-1{{Taking true branch}}
    return; // expected-warning{{Potential leak of an object stored into 'arr1'}}
            // expected-note@-1{{Object leaked}}
  arr1->release();
}

void check_dynamic_cast_null_check() {
  OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); // expected-note{{Call to method 'OSObject::generateObject' returns an OSObject}}
                                                                      // expected-warning@-1{{Potential leak of an object}}
                                                                      // expected-note@-2{{Object leaked}}
                                                                      // expected-note@-3{{Assuming dynamic cast returns null due to type mismatch}}
  if (!arr)
    return;
  arr->release();
}

void check_dynamic_cast_alias() {
  OSObject *originalPtr = OSObject::generateObject(1);   // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject}}
  OSArray *newPtr = OSDynamicCast(OSArray, originalPtr); // expected-note {{'newPtr' initialized to the value of 'originalPtr'}}
  if (newPtr) {                                          // expected-note {{'newPtr' is non-null}}
                                                         // expected-note@-1 {{Taking true branch}}
    originalPtr = OSObject::generateObject(42);
    (void)newPtr;
  }
  originalPtr->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
                          // expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}

void check_dynamic_cast_alias_cond() {
  OSObject *originalPtr = OSObject::generateObject(1); // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject}}
  OSArray *newPtr = 0;
  if ((newPtr = OSDynamicCast(OSArray, originalPtr))) { // expected-note {{The value of 'originalPtr' is assigned to 'newPtr'}}
                                                        // expected-note@-1 {{'newPtr' is non-null}}
                                                        // expected-note@-2 {{Taking true branch}}
    originalPtr = OSObject::generateObject(42);
    (void)newPtr;
  }
  originalPtr->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
                          // expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}

void check_dynamic_cast_alias_intermediate() {
  OSObject *originalPtr = OSObject::generateObject(1); // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject of type 'OSObject' with a +1 retain count}}
  OSObject *intermediate = originalPtr;                // TODO: add note here as well
  OSArray *newPtr = 0;
  if ((newPtr = OSDynamicCast(OSArray, intermediate))) { // expected-note {{The value of 'intermediate' is assigned to 'newPtr'}}
                                                         // expected-note@-1 {{'newPtr' is non-null}}
                                                         // expected-note@-2 {{Taking true branch}}
    intermediate = OSObject::generateObject(42);
    (void)newPtr;
  }
  intermediate->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
                           // expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}

void check_dynamic_cast_alias_intermediate_2() {
  OSObject *originalPtr = OSObject::generateObject(1); // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject of type 'OSObject' with a +1 retain count}}
  OSObject *intermediate = originalPtr;                // TODO: add note here as well
  OSArray *newPtr = 0;
  if ((newPtr = OSDynamicCast(OSArray, intermediate))) { // expected-note {{Value assigned to 'newPtr'}}
                                                         // expected-note@-1 {{'newPtr' is non-null}}
                                                         // expected-note@-2 {{Taking true branch}}
    intermediate = OSObject::generateObject(42);
    (void)originalPtr;
  }
  (void)newPtr;
  intermediate->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
                           // expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}

void use_after_release() {
  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
  arr->release();                           // expected-note{{Object released}}
  arr->getCount();                          // expected-warning{{Reference-counted object is used after it is released}}
                                            // expected-note@-1{{Reference-counted object is used after it is released}}
}

void potential_leak() {
  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
  arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
  arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}}
  arr->getCount();
} // expected-warning{{Potential leak of an object stored into 'arr'}}
  // expected-note@-1{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}

void proper_cleanup() {
  OSArray *arr = OSArray::withCapacity(10); // +1
  arr->retain(); // +2
  arr->release(); // +1
  arr->getCount();
  arr->release(); // 0
}

unsigned int no_warning_on_getter(ArrayOwner *owner) {
  OSArray *arr = owner->getArray();
  return arr->getCount();
}

unsigned int warn_on_overrelease(ArrayOwner *owner) {
  // FIXME: summaries are not applied in case the source of the getter/setter
  // is known.
  // rdar://45681203
  OSArray *arr = owner->getArray();
  arr->release();
  return arr->getCount();
}

unsigned int nowarn_on_release_of_created(ArrayOwner *owner) {
  OSArray *arr = owner->createArray();
  unsigned int out = arr->getCount();
  arr->release();
  return out;
}

unsigned int nowarn_on_release_of_created_source_unknown(ArrayOwner *owner) {
  OSArray *arr = owner->createArraySourceUnknown();
  unsigned int out = arr->getCount();
  arr->release();
  return out;
}

unsigned int no_warn_ok_release(ArrayOwner *owner) {
  OSArray *arr = owner->getArray(); // +0
  arr->retain(); // +1
  arr->release(); // +0
  return arr->getCount(); // no-warning
}

unsigned int warn_on_overrelease_with_unknown_source(ArrayOwner *owner) {
  OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{Call to method 'ArrayOwner::getArraySourceUnknown' returns an OSObject of type 'OSArray' with a +0 retain count}}
  arr->release(); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
                  // expected-note@-1{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
  return arr->getCount();
}

unsigned int ok_release_with_unknown_source(ArrayOwner *owner) {
  OSArray *arr = owner->getArraySourceUnknown(); // +0
  arr->retain(); // +1
  arr->release(); // +0
  return arr->getCount();
}

OSObject *getObject();
typedef bool (^Blk)(OSObject *);

void test_escape_to_unknown_block(Blk blk) {
  blk(getObject()); // no-crash
}

using OSObjectPtr = os::smart_ptr<OSObject>;

void test_smart_ptr_uaf() {
  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
  {
    OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr<OSObject>'}}
   // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}}
    // expected-note@os_smart_ptr.h:13{{Field 'pointer' is non-null}}
    // expected-note@os_smart_ptr.h:13{{Taking true branch}}
    // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}
    // expected-note@os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}}
    // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
  } // expected-note{{Calling '~smart_ptr'}}
  // expected-note@os_smart_ptr.h:35{{Field 'pointer' is non-null}}
  // expected-note@os_smart_ptr.h:35{{Taking true branch}}
  // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
  // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}}
  // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
 // expected-note@-6{{Returning from '~smart_ptr'}}
  obj->release(); // expected-note{{Object released}}
  obj->release(); // expected-warning{{Reference-counted object is used after it is released}}
// expected-note@-1{{Reference-counted object is used after it is released}}
}

void test_smart_ptr_leak() {
  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
  {
    OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr<OSObject>'}}
                        // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}}
                        // expected-note@-2 {{'p' initialized here}}
    // expected-note@os_smart_ptr.h:13{{Field 'pointer' is non-null}}
    // expected-note@os_smart_ptr.h:13{{Taking true branch}}
    // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}
    // expected-note@os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}}
    // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
  } // expected-note{{Calling '~smart_ptr'}}
  // expected-note@os_smart_ptr.h:35{{Field 'pointer' is non-null}}
  // expected-note@os_smart_ptr.h:35{{Taking true branch}}
  // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
  // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}}
  // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
  // expected-note@-6{{Returning from '~smart_ptr'}}
} // expected-warning{{Potential leak of an object stored into 'p'}}
// expected-note@-1{{Object leaked: object allocated and stored into 'p' is not referenced later in this execution path and has a retain count of +1}}

void test_smart_ptr_no_leak() {
  OSObject *obj = new OSObject;
  {
    OSObjectPtr p(obj);
  }
  obj->release();
}

void test_osmetaclass_release() {
  const char *name = "no_name";
  const OSMetaClass *meta = OSMetaClass::copyMetaClassWithName(name);
  if (!meta) {
    return;
  } else {
    meta->releaseMetaClass();
  }
}

OSObject *getRuleViolation() {
  return new OSObject; // expected-warning{{Potential leak of an object of type 'OSObject'}}
// expected-note@-1{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
// expected-note@-2{{Object leaked: allocated object of type 'OSObject' is returned from a function whose name ('getRuleViolation') starts with 'get'}}
}

OSObject *createRuleViolation(OSObject *param) { // expected-note{{Parameter 'param' starts at +0}}
  return param; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
  // expected-note@-1{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
}

void test_ostypealloc_correct_diagnostic_name() {
  OSArray *arr = OSTypeAlloc(OSArray); // expected-note{{Call to method 'OSMetaClass::alloc' returns an OSObject of type 'OSArray' with a +1 retain count}}
  arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
  arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}}
} // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
  // expected-warning@-1{{Potential leak of an object stored into 'arr'}}

void escape_elsewhere(OSObject *obj);

void test_free_on_escaped_object_diagnostics() {
  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
  escape_elsewhere(obj); // expected-note{{Object is now not exclusively owned}}
  obj->free(); // expected-note{{'free' called on an object that may be referenced elsewhere}}
  // expected-warning@-1{{'free' called on an object that may be referenced elsewhere}}
}

void test_tagged_retain_no_leak() {
  OSObject *obj = new OSObject;
  obj->taggedRelease();
}

void test_tagged_retain_no_uaf() {
  OSObject *obj = new OSObject;
  obj->taggedRetain();
  obj->release();
  obj->release();
}

class IOService {
public:
  OSObject *somethingMatching(OSObject *table = 0);
};

OSObject *testSuppressionForMethodsEndingWithMatching(IOService *svc,
                                                      OSObject *table = 0) {
  // This probably just passes table through. We should probably not make
  // ptr1 definitely equal to table, but we should not warn about leaks.
  OSObject *ptr1 = svc->somethingMatching(table); // no-warning

  // FIXME: This, however, should follow the Create Rule regardless.
  // We should warn about the leak here.
  OSObject *ptr2 = svc->somethingMatching(); // no-warning

  if (!table)
    table = OSTypeAlloc(OSArray);

  // This function itself ends with "Matching"! Do not warn when we're
  // returning from it at +0.
  return table; // no-warning
}

namespace weird_result {
struct WeirdResult {
  int x, y, z;
};

WeirdResult outParamWithWeirdResult(OS_RETURNS_RETAINED_ON_ZERO OSObject **obj);

WeirdResult testOutParamWithWeirdResult() {
  OSObject *obj;
  return outParamWithWeirdResult(&obj); // no-warning
}
} // namespace weird_result

namespace inherited_constructor_crash {
struct a {
  a(int);
};
struct b : a {
  // This is an "inherited constructor".
  using a::a;
};
void test() {
  // RetainCountChecker used to crash when looking for a summary
  // for the inherited constructor invocation.
  b(0);
}
} // namespace inherited_constructor_crash
