// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify=ref,both %s

namespace std {
  using size_t = decltype(sizeof(0));
  template<typename T> struct allocator {
    constexpr T *allocate(size_t N) {
      return (T*)operator new(sizeof(T) * N);
    }
    constexpr void deallocate(void *p) {
      operator delete(p);
    }
  };
  template<typename T, typename ...Args>
  constexpr void construct_at(void *p, Args &&...args) {
    new (p) T((Args&&)args...); // both-note {{in call to}} \
                                // both-note {{placement new would change type of storage from 'int' to 'float'}} \
                                // both-note {{construction of subobject of member 'x' of union with active member 'a' is not allowed in a constant expression}}

  }
}

void *operator new(std::size_t, void *p) { return p; }
void* operator new[] (std::size_t, void* p) {return p;}


consteval auto ok1() {
  bool b;
  new (&b) bool(true);
  return b;
}
static_assert(ok1());

consteval auto ok2() {
  int b;
  new (&b) int(12);
  return b;
}
static_assert(ok2() == 12);


consteval auto ok3() {
  float b;
  new (&b) float(12.0);
  return b;
}
static_assert(ok3() == 12.0);


consteval auto ok4() {
  _BitInt(11) b;
  new (&b) _BitInt(11)(37);
  return b;
}
static_assert(ok4() == 37);

consteval int ok5() {
  int i;
  new (&i) int[1]{1};

  struct S {
    int a; int b;
  } s;
  new (&s) S[1]{{12, 13}};

  return 25;
  // return s.a + s.b; FIXME: Broken in the current interpreter.
}
static_assert(ok5() == 25);

/// FIXME: Broken in both interpreters.
#if 0
consteval int ok5() {
    int i;
    new (&i) int[1]{1}; // expected-note {{assignment to dereferenced one-past-the-end pointer}}
    return i;
}
static_assert(ok5() == 1); // expected-error {{not an integral constant expression}} \
                           // expected-note {{in call to}}
#endif

/// FIXME: Crashes the current interpreter.
#if 0
consteval int ok6() {
    int i[2];
    new (&i) int(100);
    return i[0];
}
static_assert(ok6() == 100);
#endif

consteval int ok6() {
    int i[2];
    new (i) int(100);
    new (i + 1) int(200);
    return i[0] + i[1];
}
static_assert(ok6() == 300);


consteval auto fail1() {
  int b;
  new (&b) float(1.0); // both-note {{placement new would change type of storage from 'int' to 'float'}}
  return b;
}
static_assert(fail1() == 0); // both-error {{not an integral constant expression}} \
                             // both-note {{in call to}}

consteval int fail2() {
    int i;
    new (static_cast<void*>(&i)) float(0); // both-note {{placement new would change type of storage from 'int' to 'float'}}
    return 0;
}
static_assert(fail2() == 0); // both-error {{not an integral constant expression}} \
                             // both-note {{in call to}}

consteval int indeterminate() {
    int * indeterminate;
    new (indeterminate) int(0); // both-note {{read of uninitialized object is not allowed in a constant expression}}
    return 0;
}
static_assert(indeterminate() == 0); // both-error {{not an integral constant expression}} \
                                     // both-note {{in call to}}

consteval int array1() {
    int i[2];
    new (&i) int[]{1,2};
    return i[0] + i[1];
}
static_assert(array1() == 3);

consteval int array2() {
    int i[2];
    new (static_cast<void*>(&i)) int[]{1,2};
    return i[0] + i[1];
}
static_assert(array2() == 3);

consteval int array3() {
    int i[1];
    new (&i) int[2]; // both-note {{placement new would change type of storage from 'int[1]' to 'int[2]'}}
    return 0;
}
static_assert(array3() == 0); // both-error {{not an integral constant expression}} \
                              // both-note {{in call to}}

consteval int array4() {
    int i[2];
    new (&i) int[]{12};
    return i[0];
}
static_assert(array4() == 12);

constexpr int *intptr() {
  return new int;
}
constexpr bool yay() {
  int *ptr = new (intptr()) int(42);
  bool ret = *ptr == 42;
  delete ptr;
  return ret;
}
static_assert(yay());


constexpr bool blah() {
  int *ptr = new (intptr()) int[3]{ 1, 2, 3 }; // both-note {{placement new would change type of storage from 'int' to 'int[3]'}}
  bool ret = ptr[0] == 1 && ptr[1] == 2 && ptr[2] == 3;
  delete [] ptr;
  return ret;
}
static_assert(blah()); // both-error {{not an integral constant expression}} \
                       // both-note {{in call to 'blah()'}}


constexpr int *get_indeterminate() {
  int *evil;
  return evil; // both-note {{read of uninitialized object is not allowed in a constant expression}}
}

constexpr bool bleh() {
  int *ptr = new (get_indeterminate()) int;  // both-note {{in call to 'get_indeterminate()'}}
  return true;
}
static_assert(bleh()); // both-error {{not an integral constant expression}} \
                       // both-note {{in call to 'bleh()'}}

namespace records {
  class S {
  public:
    float f;
  };

  constexpr bool record1() {
    S s(13);
    new (&s) S(42);
    return s.f == 42;
  }
  static_assert(record1());

  S GlobalS;
  constexpr bool record2() {
    new (&GlobalS) S(42); // both-note {{a constant expression cannot modify an object that is visible outside that expression}}
    return GlobalS.f == 42;
  }
  static_assert(record2()); // both-error {{not an integral constant expression}} \
                            // both-note {{in call to}}


  constexpr bool record3() {
    S ss[3];

    new (&ss) S[]{{1}, {2}, {3}};

    return ss[0].f == 1 && ss[1].f == 2 && ss[2].f == 3;
  }
  static_assert(record3());

  struct F {
    float f;
  };
  struct R {
    F f;
    int a;
  };
  constexpr bool record4()  {
    R r;
    new (&r.f) F{42.0};
    new (&r.a) int(12);

    return r.f.f == 42.0 && r.a == 12;
  }
  static_assert(record4());

  /// Destructor is NOT called.
  struct A {
    bool b;
    constexpr ~A() { if (b) throw; }
  };

  constexpr int foo() {
    A a;
    new (&a) A(true);
    new (&a) A(false);
    return 0;
  }
  static_assert(foo() == 0);
}

namespace ConstructAt {
  struct S {
    int a = 10;
    float b = 1.0;
  };

  constexpr bool ok1() {
    S s;

    std::construct_at<S>(&s);
    return s.a == 10 && s.b == 1.0;
  }
  static_assert(ok1());

  struct S2 {
    constexpr S2() {
      (void)(1/0); // both-note {{division by zero}} \
                   // both-warning {{division by zero is undefined}}
    }
  };

  constexpr bool ctorFail() { //
    S2 *s = std::allocator<S2>().allocate(1);
    std::construct_at<S2>(s); // both-note {{in call to}}

    return true;
  }
  static_assert(ctorFail()); // both-error {{not an integral constant expression}} \
                             // both-note {{in call to 'ctorFail()'}}


  constexpr bool bad_construct_at_type() {
    int a;
    std::construct_at<float>(&a, 1.0f); // both-note {{in call to}}
    return true;
  }
  static_assert(bad_construct_at_type()); // both-error {{not an integral constant expression}} \
                                          // both-note {{in call}}

  constexpr bool bad_construct_at_subobject() {
    struct X { int a, b; };
    union A {
      int a;
      X x;
    };
    A a = {1};
    std::construct_at<int>(&a.x.a, 1); // both-note {{in call}}
    return true;
  }
  static_assert(bad_construct_at_subobject()); // both-error{{not an integral constant expression}} \
                                               // both-note {{in call}}
}

namespace UsedToCrash {
  struct S {
      int* i;
      constexpr S() : i(new int(42)) {} // #no-deallocation
      constexpr ~S() {delete i;}
  };
  consteval void alloc() {
      S* s = new S();
      s->~S();
      new (s) S();
      delete s;
  }
  int alloc1 = (alloc(), 0);
}

constexpr bool change_union_member() {
  union U {
    int a;
    int b;
  };
  U u = {.a = 1};
  std::construct_at<int>(&u.b, 2);
  return u.b == 2;
}
static_assert(change_union_member());

namespace PR48606 {
  struct A { mutable int n = 0; };

  constexpr bool f() {
    A a;
    A *p = &a;
    p->~A();
    std::construct_at<A>(p);
    return true;
  }
  static_assert(f());
}
