// 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 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@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 '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 test_smart_ptr_no_leak() {
  OSObject *obj = new OSObject;
  {
    OSObjectPtr p(obj);
  }
  obj->release();
}

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
