mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
185 lines
5.2 KiB
C++
185 lines
5.2 KiB
C++
// semmle-extractor-options: -std=c++20
|
|
typedef unsigned long size_t;
|
|
namespace std {
|
|
enum class align_val_t : size_t {};
|
|
|
|
struct destroying_delete_t {
|
|
explicit destroying_delete_t() = default;
|
|
};
|
|
inline constexpr destroying_delete_t destroying_delete{};
|
|
}
|
|
|
|
void* operator new(size_t, float);
|
|
void* operator new[](size_t, float);
|
|
void* operator new(size_t, std::align_val_t, float);
|
|
void* operator new[](size_t, std::align_val_t, float);
|
|
void operator delete(void*, float);
|
|
void operator delete[](void*, float);
|
|
void operator delete(void*, std::align_val_t, float);
|
|
void operator delete[](void*, std::align_val_t, float);
|
|
|
|
struct String {
|
|
String();
|
|
String(const String&);
|
|
String(String&&);
|
|
String(const char*);
|
|
~String();
|
|
|
|
String& operator=(const String&);
|
|
String& operator=(String&&);
|
|
|
|
const char* c_str() const;
|
|
|
|
private:
|
|
const char* p;
|
|
};
|
|
|
|
struct SizedDealloc {
|
|
char a[32];
|
|
void* operator new(size_t);
|
|
void* operator new[](size_t);
|
|
void operator delete(void*, size_t);
|
|
void operator delete[](void*, size_t);
|
|
};
|
|
|
|
struct DestroyingDealloc {
|
|
void* operator new(size_t);
|
|
void operator delete(DestroyingDealloc*, std::destroying_delete_t);
|
|
};
|
|
|
|
struct alignas(128) Overaligned {
|
|
char a[256];
|
|
};
|
|
|
|
struct PolymorphicBase {
|
|
virtual ~PolymorphicBase();
|
|
};
|
|
|
|
void OperatorNew() {
|
|
new int; // No constructor
|
|
new(1.0f) int; // Placement new, no constructor
|
|
new int(); // Zero-init
|
|
new String(); // Constructor
|
|
new(1.0f) String("hello"); // Placement new, constructor with args
|
|
new Overaligned; // Aligned new
|
|
new(1.0f) Overaligned(); // Placement aligned new
|
|
}
|
|
|
|
void OperatorDelete() {
|
|
delete static_cast<int*>(nullptr); // No destructor
|
|
delete static_cast<String*>(nullptr); // Non-virtual destructor, with size.
|
|
delete static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
|
|
delete static_cast<DestroyingDealloc*>(nullptr); // No destructor, with destroying delete.
|
|
delete static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
|
|
delete static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
|
|
delete static_cast<const String*>(nullptr); // Pointer to const
|
|
}
|
|
|
|
void OperatorNewArray(int n) {
|
|
new int[n]; // No constructor
|
|
new(1.0f) int[n]; // Placement new, no constructor
|
|
new String[n]; // Constructor
|
|
new Overaligned[n]; // Aligned new
|
|
new String[10]; // Constant size
|
|
}
|
|
|
|
int* const GetPointer();
|
|
|
|
void OperatorDeleteArray() {
|
|
delete[] static_cast<int*>(nullptr); // No destructor
|
|
delete[] static_cast<String*>(nullptr); // Non-virtual destructor, with size.
|
|
delete[] static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
|
|
delete[] static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
|
|
delete[] static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
|
|
delete[] GetPointer();
|
|
}
|
|
|
|
struct FailedInit {
|
|
FailedInit();
|
|
~FailedInit();
|
|
|
|
void* operator new(size_t); // Non-placement
|
|
void* operator new[](size_t); // Non-placement
|
|
void operator delete(void*, size_t); // Sized deallocation
|
|
void operator delete[](void*, size_t); // Sized deallocation
|
|
};
|
|
|
|
struct alignas(128) FailedInitOveraligned {
|
|
FailedInitOveraligned();
|
|
~FailedInitOveraligned();
|
|
|
|
void* operator new(size_t, std::align_val_t, float); // Aligned placement
|
|
void* operator new[](size_t, std::align_val_t, float); // Aligned placement
|
|
void operator delete(void*, std::align_val_t, float); // Aligned placement
|
|
void operator delete[](void*, std::align_val_t, float); // Aligned placement
|
|
};
|
|
|
|
struct alignas(128) FailedInitDestroyingDelete {
|
|
FailedInitDestroyingDelete();
|
|
~FailedInitDestroyingDelete();
|
|
|
|
void* operator new(size_t); // Non-placement
|
|
void operator delete(FailedInitDestroyingDelete*, std::destroying_delete_t); // Destroying delete
|
|
};
|
|
|
|
void TestFailedInit(int n) {
|
|
new FailedInit();
|
|
new FailedInit[n];
|
|
new(1.0f) FailedInitOveraligned();
|
|
new(1.0f) FailedInitOveraligned[10];
|
|
new FailedInitDestroyingDelete();
|
|
}
|
|
|
|
// --- non-allocating placement new ---
|
|
|
|
namespace std {
|
|
typedef unsigned long size_t;
|
|
struct nothrow_t {};
|
|
extern const nothrow_t nothrow;
|
|
}
|
|
|
|
void* operator new (std::size_t size, void* ptr) noexcept;
|
|
void* operator new[](std::size_t size, void* ptr) noexcept;
|
|
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
|
|
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
|
|
|
|
int overloadedNew() {
|
|
char buf[sizeof(int)];
|
|
|
|
new(&buf[0]) int(5);
|
|
int five = *(int*)buf;
|
|
|
|
new(buf) int[1];
|
|
*(int*)buf = 4;
|
|
|
|
new(std::nothrow) int(3); // memory leak
|
|
new(std::nothrow) int[2]; // memory leak
|
|
|
|
return five;
|
|
}
|
|
|
|
void multidimensionalNew(int x, int y) {
|
|
auto p1 = new char[x][10];
|
|
auto p2 = new char[20][20];
|
|
auto p3 = new char[x][30][30];
|
|
}
|
|
|
|
void directOperatorCall() {
|
|
void *ptr;
|
|
ptr = operator new(sizeof(int));
|
|
operator delete(ptr);
|
|
}
|
|
|
|
void *malloc(size_t);
|
|
typedef int* ptr_int;
|
|
|
|
void testMalloc(size_t count) {
|
|
const volatile int *i = (const volatile int *) malloc(5);
|
|
ptr_int i2 = (ptr_int) malloc(5 * sizeof(int));
|
|
volatile long *l = (long *) malloc(count);
|
|
l = (long *) malloc(count * sizeof(int));
|
|
const char* c = (const char *) malloc(count * sizeof(int) + 1);
|
|
void * v = (void *) malloc(((int) count) * sizeof(void *));
|
|
malloc(sizeof(void *) * sizeof(int));
|
|
}
|