// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors -Wno-null-dereference -Wno-inaccessible-base -verify -analyzer-config eagerly-assume=false %s

void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);

class A {
public:
  ~A() { 
    int *x = 0;
    *x = 3; // expected-warning{{Dereference of null pointer}}
  }
};

int main() {
  A a;
}


typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
void free(void *);

class SmartPointer {
  void *X;
public:
  SmartPointer(void *x) : X(x) {}
  ~SmartPointer() {
    free(X);
  }
};

void testSmartPointer() {
  char *mem = (char*)malloc(4);
  {
    SmartPointer Deleter(mem);
    // destructor called here
  }
  *mem = 0; // expected-warning{{Use of memory after it is freed}}
}


void doSomething();
void testSmartPointer2() {
  char *mem = (char*)malloc(4);
  {
    SmartPointer Deleter(mem);
    // Remove dead bindings...
    doSomething();
    // destructor called here
  }
  *mem = 0; // expected-warning{{Use of memory after it is freed}}
}


class Subclass : public SmartPointer {
public:
  Subclass(void *x) : SmartPointer(x) {}
};

void testSubclassSmartPointer() {
  char *mem = (char*)malloc(4);
  {
    Subclass Deleter(mem);
    // Remove dead bindings...
    doSomething();
    // destructor called here
  }
  *mem = 0; // expected-warning{{Use of memory after it is freed}}
}


class MultipleInheritance : public Subclass, public SmartPointer {
public:
  MultipleInheritance(void *a, void *b) : Subclass(a), SmartPointer(b) {}
};

void testMultipleInheritance1() {
  char *mem = (char*)malloc(4);
  {
    MultipleInheritance Deleter(mem, 0);
    // Remove dead bindings...
    doSomething();
    // destructor called here
  }
  *mem = 0; // expected-warning{{Use of memory after it is freed}}
}

void testMultipleInheritance2() {
  char *mem = (char*)malloc(4);
  {
    MultipleInheritance Deleter(0, mem);
    // Remove dead bindings...
    doSomething();
    // destructor called here
  }
  *mem = 0; // expected-warning{{Use of memory after it is freed}}
}

void testMultipleInheritance3() {
  char *mem = (char*)malloc(4);
  {
    MultipleInheritance Deleter(mem, mem);
    // Remove dead bindings...
    doSomething();
    // destructor called here
    // expected-warning@28 {{Attempt to free released memory}}
  }
}


class SmartPointerMember {
  SmartPointer P;
public:
  SmartPointerMember(void *x) : P(x) {}
};

void testSmartPointerMember() {
  char *mem = (char*)malloc(4);
  {
    SmartPointerMember Deleter(mem);
    // Remove dead bindings...
    doSomething();
    // destructor called here
  }
  *mem = 0; // expected-warning{{Use of memory after it is freed}}
}


struct IntWrapper {
  IntWrapper() : x(0) {}
  ~IntWrapper();
  int *x;
};

void testArrayInvalidation() {
  int i = 42;
  int j = 42;

  {
    IntWrapper arr[2];

    // There should be no undefined value warnings here.
    // Eventually these should be TRUE as well, but right now
    // we can't handle array constructors.
    clang_analyzer_eval(arr[0].x == 0); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(arr[1].x == 0); // expected-warning{{UNKNOWN}}

    arr[0].x = &i;
    arr[1].x = &j;
    clang_analyzer_eval(*arr[0].x == 42); // expected-warning{{TRUE}}
    clang_analyzer_eval(*arr[1].x == 42); // expected-warning{{TRUE}}
  }

  // The destructors should have invalidated i and j.
  clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
  clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
}



// Don't crash on a default argument inside an initializer.
struct DefaultArg {
  DefaultArg(int x = 0) {}
  ~DefaultArg();
};

struct InheritsDefaultArg : DefaultArg {
  InheritsDefaultArg() {}
  virtual ~InheritsDefaultArg();
};

void testDefaultArg() {
  InheritsDefaultArg a;
  // Force a bug to be emitted.
  *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
}


namespace DestructorVirtualCalls {
  class A {
  public:
    int *out1, *out2, *out3;

    virtual int get() { return 1; }

    ~A() {
      *out1 = get();
    }
  };

  class B : public A {
  public:
    virtual int get() { return 2; }

    ~B() {
      *out2 = get();
    }
  };

  class C : public B {
  public:
    virtual int get() { return 3; }

    ~C() {
      *out3 = get();
    }
  };

  void test() {
    int a, b, c;

    // New scope for the C object.
    {
      C obj;
      clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}

      // Correctness check for devirtualization.
      A *base = &obj;
      clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}

      obj.out1 = &a;
      obj.out2 = &b;
      obj.out3 = &c;
    }

    clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
    clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
    clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
  }
}


namespace DestructorsShouldNotAffectReturnValues {
  class Dtor {
  public:
    ~Dtor() {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
    }
  };

  void *allocate() {
    Dtor d;
    return malloc(4); // no-warning
  }

  void test() {
    // At one point we had an issue where the statements inside an
    // inlined destructor kept us from finding the return statement,
    // leading the analyzer to believe that the malloc'd memory had leaked.
    void *p = allocate();
    free(p); // no-warning
  }
}

namespace MultipleInheritanceVirtualDtors {
  class VirtualDtor {
  protected:
    virtual ~VirtualDtor() {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
    }
  };

  class NonVirtualDtor {
  protected:
    ~NonVirtualDtor() {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
    }
  };

  class SubclassA : public VirtualDtor, public NonVirtualDtor {
  public:
    virtual ~SubclassA() {}
  };
  class SubclassB : public NonVirtualDtor, public VirtualDtor {
  public:
    virtual ~SubclassB() {}
  };

  void test() {
    SubclassA a;
    SubclassB b;
  }
}

namespace ExplicitDestructorCall {
  class VirtualDtor {
  public:
    virtual ~VirtualDtor() {
      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
    }
  };
  
  class Subclass : public VirtualDtor {
  public:
    virtual ~Subclass() {
      clang_analyzer_checkInlined(false); // no-warning
    }
  };
  
  void destroy(Subclass *obj) {
    obj->VirtualDtor::~VirtualDtor();
  }
}


namespace MultidimensionalArrays {
  void testArrayInvalidation() {
    int i = 42;
    int j = 42;

    {
      IntWrapper arr[2][2];

      // There should be no undefined value warnings here.
      // Eventually these should be TRUE as well, but right now
      // we can't handle array constructors.
      clang_analyzer_eval(arr[0][0].x == 0); // expected-warning{{UNKNOWN}}
      clang_analyzer_eval(arr[1][1].x == 0); // expected-warning{{UNKNOWN}}

      arr[0][0].x = &i;
      arr[1][1].x = &j;
      clang_analyzer_eval(*arr[0][0].x == 42); // expected-warning{{TRUE}}
      clang_analyzer_eval(*arr[1][1].x == 42); // expected-warning{{TRUE}}
    }

    // The destructors should have invalidated i and j.
    clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
    clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
  }
}

namespace LifetimeExtension {
  struct IntWrapper {
	int x;
	IntWrapper(int y) : x(y) {}
	IntWrapper() {
      extern void use(int);
      use(x); // no-warning
	}
  };

  struct DerivedWrapper : public IntWrapper {
	DerivedWrapper(int y) : IntWrapper(y) {}
  };

  DerivedWrapper get() {
	return DerivedWrapper(1);
  }

  void test() {
	const DerivedWrapper &d = get(); // lifetime extended here
  }


  class SaveOnDestruct {
  public:
    static int lastOutput;
    int value;

    SaveOnDestruct();
    ~SaveOnDestruct() {
      lastOutput = value;
    }
  };

  void testSimple() {
    {
      const SaveOnDestruct &obj = SaveOnDestruct();
      if (obj.value != 42)
        return;
      // destructor called here
    }

    clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}}
  }

  struct NRCheck {
    bool bool_;
    NRCheck():bool_(true) {}
    ~NRCheck() __attribute__((noreturn));
    operator bool() const { return bool_; }
  };

  struct CheckAutoDestructor {
    bool bool_;
    CheckAutoDestructor():bool_(true) {}
    operator bool() const { return bool_; }
  };

  struct CheckCustomDestructor {
    bool bool_;
    CheckCustomDestructor():bool_(true) {}
    ~CheckCustomDestructor();
    operator bool() const { return bool_; }
  };

  bool testUnnamedNR() {
    if (NRCheck())
      return true;
    return false;
  }

  bool testNamedNR() {
    if (NRCheck c = NRCheck())
      return true;
    return false;
  }

  bool testUnnamedAutoDestructor() {
    if (CheckAutoDestructor())
      return true;
    return false;
  }

  bool testNamedAutoDestructor() {
    if (CheckAutoDestructor c = CheckAutoDestructor())
      return true;
    return false;
  }

  bool testUnnamedCustomDestructor() {
    if (CheckCustomDestructor())
      return true;
    return false;
  }

  // This case used to cause an unexpected "Undefined or garbage value returned
  // to caller" warning
  bool testNamedCustomDestructor() {
    if (CheckCustomDestructor c = CheckCustomDestructor())
      return true;
    return false;
  }

  bool testMultipleTemporariesCustomDestructor() {
    if (CheckCustomDestructor c = (CheckCustomDestructor(), CheckCustomDestructor()))
      return true;
    return false;
  }

  class VirtualDtorBase {
  public:
    int value;
    virtual ~VirtualDtorBase() {}
  };

  class SaveOnVirtualDestruct : public VirtualDtorBase {
  public:
    static int lastOutput;

    SaveOnVirtualDestruct();
    virtual ~SaveOnVirtualDestruct() {
      lastOutput = value;
    }
  };

  void testVirtual() {
    {
      const VirtualDtorBase &obj = SaveOnVirtualDestruct();
      if (obj.value != 42)
        return;
      // destructor called here
    }

    clang_analyzer_eval(SaveOnVirtualDestruct::lastOutput == 42); // expected-warning{{TRUE}}
  }
}

namespace NoReturn {
  struct NR {
    ~NR() __attribute__((noreturn));
  };

  void f(int **x) {
    NR nr;
  }

  void g() {
    int *x;
    f(&x);
    *x = 47; // no warning
  }

  void g2(int *x) {
    if (! x) NR();
    *x = 47; // no warning
  }
}

namespace PseudoDtor {
  template <typename T>
  void destroy(T &obj) {
    clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
    obj.~T();
  }

  void test() {
    int i;
    destroy(i);
    clang_analyzer_eval(true); // expected-warning{{TRUE}}
  }
}

namespace Incomplete {
  class Foo; // expected-note{{forward declaration}}
  void f(Foo *foo) { delete foo; } // expected-warning{{deleting pointer to incomplete type}}
}

namespace TypeTraitExpr {
template <bool IsSimple, typename T>
struct copier {
  static void do_copy(T *dest, const T *src, unsigned count);
};
template <typename T, typename U>
void do_copy(T *dest, const U *src, unsigned count) {
  const bool IsSimple = __is_trivial(T) && __is_same(T, U);
  copier<IsSimple, T>::do_copy(dest, src, count);
}
struct NonTrivial {
  int *p;
  NonTrivial() : p(new int[1]) { p[0] = 0; }
  NonTrivial(const NonTrivial &other) {
    p = new int[1];
    do_copy(p, other.p, 1);
  }
  NonTrivial &operator=(const NonTrivial &other) {
    p = other.p;
    return *this;
  }
  ~NonTrivial() {
    delete[] p; // expected-warning {{free released memory}}
  }
};

void f() {
  NonTrivial nt1;
  NonTrivial nt2(nt1);
  nt1 = nt2;
  clang_analyzer_eval(__is_trivial(NonTrivial)); // expected-warning{{FALSE}}
  clang_analyzer_eval(__alignof(NonTrivial) > 0); // expected-warning{{TRUE}}
}
}

namespace dtor_over_loc_concrete_int {
struct A {
  ~A() {}
};

struct B {
  A a;
  ~B() {}
};

struct C : A {
  ~C() {}
};

void testB() {
  B *b = (B *)-1;
  b->~B(); // no-crash
}

void testC() {
  C *c = (C *)-1;
  c->~C(); // no-crash
}

void testAutoDtor() {
  const A &a = *(A *)-1;
  // no-crash
}
} // namespace dtor_over_loc_concrete_int
