Add tests that std::unique_ptr's default constructor is constexpr.

std::unique_ptr's default constructor must be constexpr in order
to allow constant initialization to take place for static objects;
Even though we can never have a constexpr unique_ptr variable since
it's not a literal type.

This patch adds tests that constant initialization takes place by
using the __attribute__((require_constant_initialization)) macro.

llvm-svn: 300158
This commit is contained in:
Eric Fiselier 2017-04-13 01:11:58 +00:00
parent fde9aafe3d
commit ed9caee9a8
3 changed files with 50 additions and 49 deletions

View File

@ -17,31 +17,34 @@
#include <memory>
#include <cassert>
#include "test_macros.h"
class Deleter
{
int state_;
#if defined(_LIBCPP_VERSION)
_LIBCPP_SAFE_STATIC std::unique_ptr<int[]> global_static_unique_ptr;
#endif
Deleter(Deleter&);
Deleter& operator=(Deleter&);
class Deleter {
int state_;
Deleter(Deleter&);
Deleter& operator=(Deleter&);
public:
Deleter() : state_(5) {}
Deleter() : state_(5) {}
int state() const {return state_;}
int state() const { return state_; }
void operator()(void*) {}
void operator()(void*) {}
};
int main()
{
{
int main() {
{
std::unique_ptr<int[]> p;
assert(p.get() == 0);
}
{
}
{
std::unique_ptr<int[], Deleter> p;
assert(p.get() == 0);
assert(p.get_deleter().state() == 5);
}
}
}

View File

@ -20,65 +20,58 @@
struct A;
class Deleter
{
int state_;
class Deleter {
int state_;
Deleter(Deleter&);
Deleter& operator=(Deleter&);
Deleter(Deleter&);
Deleter& operator=(Deleter&);
public:
Deleter() : state_(5) {}
Deleter() : state_(5) {}
int state() const {return state_;}
int state() const { return state_; }
void operator()(A* p);
void operator()(A* p);
};
void check(int i);
template <class D = std::default_delete<A> >
struct B
{
std::unique_ptr<A[], D> a_;
B();
~B();
template <class D = std::default_delete<A>>
struct B {
std::unique_ptr<A[], D> a_;
B();
~B();
A* get() const {return a_.get();}
D& get_deleter() {return a_.get_deleter();}
A* get() const { return a_.get(); }
D& get_deleter() { return a_.get_deleter(); }
};
int main()
{
{
int main() {
{
B<> s;
assert(s.get() == 0);
}
check(0);
{
}
check(0);
{
B<Deleter> s;
assert(s.get() == 0);
assert(s.get_deleter().state() == 5);
}
check(0);
}
check(0);
}
struct A
{
static int count;
A() {++count;}
A(const A&) {++count;}
~A() {--count;}
struct A {
static int count;
A() { ++count; }
A(const A&) { ++count; }
~A() { --count; }
};
int A::count = 0;
void Deleter::operator()(A* p) {delete p;}
void Deleter::operator()(A* p) { delete p; }
void check(int i)
{
assert(A::count == i);
}
void check(int i) { assert(A::count == i); }
template <class D>
B<D>::B() {}

View File

@ -25,9 +25,14 @@
#include <memory>
#include <cassert>
#include "test_macros.h"
#include "deleter_types.h"
#if defined(_LIBCPP_VERSION)
_LIBCPP_SAFE_STATIC std::unique_ptr<int> global_static_unique_ptr;
#endif
struct IncompleteT;
void checkNumIncompleteTypeAlive(int i);