// 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.
    clang_analyzer_eval(arr[0].x == 0); // expected-warning{{TRUE}}
    clang_analyzer_eval(arr[1].x == 0); // expected-warning{{TRUE}}

    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.
      clang_analyzer_eval(arr[0][0].x == 0); // expected-warning{{TRUE}}
      clang_analyzer_eval(arr[1][1].x == 0); // expected-warning{{TRUE}}

      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

// Test overriden new/delete operators
struct CustomOperators {
  void *operator new(size_t count) {
    return malloc(count);
  }

  void operator delete(void *addr) {
    free(addr);
  }

private:
  int i;
};

void compliant() {
  auto *a = new CustomOperators();
  delete a;
}

void overrideLeak() {
  auto *a = new CustomOperators();
} // expected-warning{{Potential leak of memory pointed to by 'a'}}

void overrideDoubleDelete() {
  auto *a = new CustomOperators();
  delete a;
  delete a; // expected-warning@577 {{Attempt to free released memory}}
}
