//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

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

#include <vector>
#include <cassert>

#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 should_throw) : should_throw(should_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() {
#ifndef _LIBCPP_HAS_NO_VARIADICS
  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 // _LIBCPP_HAS_NO_VARIADICS
}

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() {
#ifndef _LIBCPP_HAS_NO_VARIADICS
  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 // _LIBCPP_HAS_NO_VARIADICS
}

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() {
  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();
}
