You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.1 KiB
159 lines
3.1 KiB
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include <memory>
|
|
|
|
namespace unique_ptr {
|
|
|
|
struct X {
|
|
int field;
|
|
int get() { return field; }
|
|
void set(int value) { field = value; }
|
|
};
|
|
|
|
int empty_ptr_access() {
|
|
std::unique_ptr<int> x;
|
|
int* p = x.get(); // no dereference
|
|
if (p) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int FN_empty_ptr_deref_bad() {
|
|
std::unique_ptr<int> x;
|
|
return *x;
|
|
}
|
|
|
|
int FN_empty_array_ptr_deref_bad() {
|
|
std::unique_ptr<int[]> x;
|
|
return x[0];
|
|
}
|
|
|
|
int FN_nullptr_ptr_deref_bad() {
|
|
std::unique_ptr<int> x(nullptr);
|
|
return *x;
|
|
}
|
|
|
|
int FN_nullptr_array_ptr_deref_bad() {
|
|
std::unique_ptr<int[]> x(nullptr);
|
|
return x[2];
|
|
}
|
|
|
|
int FN_empty_ptr_field_deref_bad() {
|
|
std::unique_ptr<X> x;
|
|
return x.get()->field;
|
|
}
|
|
|
|
int FN_empty_ptr_field_deref2_bad() {
|
|
std::unique_ptr<X> x;
|
|
return x->field;
|
|
}
|
|
|
|
int FN_empty_ptr_method_deref_bad() {
|
|
std::unique_ptr<X> x;
|
|
return x->get();
|
|
}
|
|
|
|
// FP is memory leak
|
|
int FN_FP_reset_ptr_null_deref_bad() {
|
|
std::unique_ptr<int> x(new int);
|
|
x.reset();
|
|
return *x;
|
|
}
|
|
|
|
int FN_FP_reset_ptr_null_deref2_bad() {
|
|
std::unique_ptr<int> x(new int);
|
|
x.reset(new int);
|
|
x.reset();
|
|
return *x;
|
|
}
|
|
|
|
int FP_reset_ptr_deref_ok() {
|
|
std::unique_ptr<int> x;
|
|
x.reset(new int);
|
|
return *x;
|
|
}
|
|
|
|
int FP_reset_ptr_deref2_ok() {
|
|
std::unique_ptr<int> x;
|
|
x.reset();
|
|
x.reset(new int);
|
|
return *x;
|
|
}
|
|
|
|
int FN_unique_ptr_copy_null_deref_bad() {
|
|
std::unique_ptr<int> p1;
|
|
std::unique_ptr<int> p2 = std::move(p1);
|
|
return *p2;
|
|
}
|
|
|
|
int FN_unique_ptr_assign_null_deref_bad() {
|
|
std::unique_ptr<int> p1(new int);
|
|
std::unique_ptr<int> p2;
|
|
p1 = std::move(p2);
|
|
return *p1;
|
|
}
|
|
|
|
int FP_unique_ptr_move_deref_ok() {
|
|
std::unique_ptr<int> p1(new int);
|
|
std::unique_ptr<int> p2 = std::move(p1);
|
|
return *p2;
|
|
}
|
|
|
|
int unique_ptr_assign_deref_ok() {
|
|
std::unique_ptr<int> p1(new int);
|
|
std::unique_ptr<int> p2;
|
|
p2 = std::move(p1);
|
|
p1.reset();
|
|
return *p2;
|
|
}
|
|
|
|
int FN_unique_ptr_move_null_deref_bad() {
|
|
std::unique_ptr<int> p1(new int);
|
|
std::unique_ptr<int> p2 = std::move(p1);
|
|
return *p1;
|
|
}
|
|
|
|
} // namespace unique_ptr
|
|
|
|
namespace unique_ptr_with_deleter {
|
|
|
|
/* This is just a compilation test */
|
|
|
|
template <class T>
|
|
class Pointer {
|
|
public:
|
|
/* No constructor with only one T* argument */
|
|
/* implicit */ Pointer(std::nullptr_t = nullptr) noexcept {}
|
|
Pointer(T* ptr, int n) noexcept {}
|
|
|
|
friend bool operator==(Pointer a, Pointer b) noexcept { return true; }
|
|
friend bool operator!=(Pointer a, Pointer b) noexcept { return true; }
|
|
explicit operator bool() const noexcept { return true; }
|
|
T* operator->() const noexcept { return get(); }
|
|
T& operator*() const noexcept { return *get(); }
|
|
T* get() const noexcept { return nullptr; }
|
|
};
|
|
|
|
template <class T>
|
|
struct Deleter {
|
|
using pointer = Pointer<T>;
|
|
|
|
void operator()(pointer ptr) const {}
|
|
};
|
|
|
|
template <class T>
|
|
using my_unique_ptr = std::unique_ptr<T, Deleter<T>>;
|
|
|
|
bool instantiate() {
|
|
my_unique_ptr<int> p;
|
|
my_unique_ptr<int[]> q;
|
|
return p != nullptr && q != nullptr;
|
|
}
|
|
} // namespace unique_ptr_with_deleter
|