//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: libcpp-no-exceptions
// Test asan vector annotations with a class that throws in a CTOR.

#include <vector>
#include <cassert>

#include "test_macros.h"
#include "asan_testing.h"

class X {
public:
  X(const X &x) { Init(x.a); }
  X(char arg) { Init(arg); }
  X() { Init(42); }
  X &operator=(const X &x) {
    Init(x.a);
    return *this;
  }
  void Init(char arg) {
    if (arg == 42)
      throw 0;
    if (arg == 66)
      arg = 42;
    a = arg;
  }
  char get() const { return a; }
  void set(char arg) { a = arg; }

private:
  char a;
};

class ThrowOnCopy {
public:
    ThrowOnCopy() : should_throw(false) {}
    explicit ThrowOnCopy(bool xshould_throw) : should_throw(xshould_throw) {}

    ThrowOnCopy(ThrowOnCopy const & other)
        : should_throw(other.should_throw)
    {
        if (should_throw) {
            throw 0;
        }
    }

    bool should_throw;
};

void test_push_back() {
  std::vector<X> v;
  v.reserve(2);
  v.push_back(X(2));
  assert(v.size() == 1);
  try {
    v.push_back(X(66));
    assert(0);
  } catch (int e) {
    assert(v.size() == 1);
  }
  assert(v.size() == 1);
  assert(is_contiguous_container_asan_correct(v));
}

void test_emplace_back() {
#if TEST_STD_VER >= 11
  std::vector<X> v;
  v.reserve(2);
  v.push_back(X(2));
  assert(v.size() == 1);
  try {
    v.emplace_back(42);
    assert(0);
  } catch (int e) {
    assert(v.size() == 1);
  }
  assert(v.size() == 1);
  assert(is_contiguous_container_asan_correct(v));
#endif
}

void test_insert_range() {
  std::vector<X> v;
  v.reserve(4);
  v.push_back(X(1));
  v.push_back(X(2));
  assert(v.size() == 2);
  assert(v.capacity() >= 4);
  try {
    char a[2] = {21, 42};
    v.insert(v.end(), a, a + 2);
    assert(0);
  } catch (int e) {
    assert(v.size() == 3);
  }
  assert(v.size() == 3);
  assert(is_contiguous_container_asan_correct(v));
}

void test_insert() {
  std::vector<X> v;
  v.reserve(3);
  v.insert(v.end(), X(1));
  v.insert(v.begin(), X(2));
  assert(v.size() == 2);
  try {
    v.insert(v.end(), X(66));
    assert(0);
  } catch (int e) {
    assert(v.size() == 2);
  }
  assert(v.size() == 2);
  assert(is_contiguous_container_asan_correct(v));
}

void test_emplace() {
#if TEST_STD_VER >= 11
  std::vector<X> v;
  v.reserve(3);
  v.insert(v.end(), X(1));
  v.insert(v.begin(), X(2));
  assert(v.size() == 2);
  try {
    v.emplace(v.end(), 42);
    assert(0);
  } catch (int e) {
    assert(v.size() == 2);
  }
  assert(v.size() == 2);
  assert(is_contiguous_container_asan_correct(v));
#endif
}

void test_insert_range2() {
  std::vector<X> v;
  v.reserve(4);
  v.insert(v.end(), X(1));
  v.insert(v.begin(), X(2));
  assert(v.size() == 2);
  assert(v.capacity() >= 4);
  try {
    char a[2] = {10, 42};
    v.insert(v.begin(), a, a + 2);
    assert(0);
  } catch (int e) {
    assert(v.size() <= 4);
    assert(is_contiguous_container_asan_correct(v));
    return;
  }
  assert(0);
}

void test_insert_n() {
  std::vector<X> v;
  v.reserve(10);
  v.insert(v.end(), X(1));
  v.insert(v.begin(), X(2));
  assert(v.size() == 2);
  try {
    v.insert(v.begin(), 1, X(66));
    assert(0);
  } catch (int e) {
    assert(v.size() <= 3);
    assert(is_contiguous_container_asan_correct(v));
    return;
  }
  assert(0);
}


void test_insert_n2() {
  std::vector<ThrowOnCopy> v(10);
  v.reserve(100);
  assert(v.size() == 10);
  v[6].should_throw = true;
  try {
    v.insert(v.cbegin(), 5, ThrowOnCopy());
    assert(0);
  } catch (int e) {
    assert(v.size() == 11);
    assert(is_contiguous_container_asan_correct(v));
    return;
  }
  assert(0);
}

void test_resize() {
  std::vector<X> v;
  v.reserve(3);
  v.push_back(X(0));
  try {
    v.resize(3);
    assert(0);
  } catch (int e) {
    assert(v.size() == 1);
  }
  assert(v.size() == 1);
  assert(is_contiguous_container_asan_correct(v));
}

void test_resize_param() {
  std::vector<X> v;
  v.reserve(3);
  v.push_back(X(0));
  try {
    v.resize(3, X(66));
    assert(0);
  } catch (int e) {
    assert(v.size() == 1);
  }
  assert(v.size() == 1);
  assert(is_contiguous_container_asan_correct(v));
}

int main(int, char**) {
  test_push_back();
  test_emplace_back();
  test_insert_range();
  test_insert();
  test_emplace();
  test_insert_range2();
  test_insert_n();
  test_insert_n2();
  test_resize();
  test_resize_param();

  return 0;
}
