================ @@ -165,3 +165,124 @@ void LValueToRValueBitCast_dumps(void *p, char (*array)[8]) { unsigned long ptr_arithmetic(void *p) { return __builtin_bit_cast(unsigned long, p) + 1; // no-crash } + + +void escape(int*); + +struct AllocOpaqueFlag {}; + +void* operator new(unsigned long, void *ptr) noexcept { return ptr; } +void* operator new(unsigned long, void *ptr, AllocOpaqueFlag const&) noexcept { return ptr; } + +void* operator new[](unsigned long, void* ptr) noexcept { return ptr; } +void* operator new[](unsigned long, void* ptr, AllocOpaqueFlag const&); + +struct Buffer { + char buf[100]; + int padding; +}; + +void checkPlacementNewArryInObject() { + Buffer buffer; + int* array = new (&buffer) int[10]; + escape(array); + ++array; // no warning + (void)*array; +} + +void checkPlacementNewArrayInObjectOpaque() { + Buffer buffer; + int* array = new (&buffer, AllocOpaqueFlag{}) int[10]; + escape(array); + ++array; // no warning + (void)*array; +} + +void checkPlacementNewArrayInArray() { + char buffer[100]; + int* array = new (buffer) int[10]; + escape(array); + ++array; // no warning + (void)*array; +} + +void checkPlacementNewArrayInArrayOpaque() { + char buffer[100]; + int* array = new (buffer, AllocOpaqueFlag{}) int; + escape(array); + ++array; // no warning + (void)*array; +} + +void checkPlacementNewObjectInObject() { + Buffer buffer; + int* array = new (&buffer) int; + escape(array); + ++array; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}} + (void)*array; +} + +void checkPlacementNewObjectInObjectOpaque() { + Buffer buffer; + int* array = new (&buffer, AllocOpaqueFlag{}) int; + escape(array); + ++array; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}} + (void)*array; +} + +void checkPlacementNewObjectInArray() { + char buffer[sizeof(int)]; + int* array = new (buffer) int; + escape(array); + ++array; // no warning (FN) + (void)*array; +} + +void checkPlacementNewObjectInArrayOpaque() { + char buffer[sizeof(int)]; + int* array = new (buffer, AllocOpaqueFlag{}) int; + escape(array); + ++array; // no warning (FN) + (void)*array; +} + +void checkPlacementNewSlices() { + const int N = 10; + char buffer[sizeof(int) * N] = {0}; + int *start = new (buffer) int{0}; + for (int i = 1; i < N; i++) { + auto *ptr = new int(buffer[i * sizeof(int)]); + *ptr = i; + } + ++start; // no warning + (void*)start; +} + +class BumpAlloc { + char *buffer; + char *offset; +public: + BumpAlloc(int n): buffer(new char[n]), offset{buffer} {} + ~BumpAlloc() {delete [] buffer;} ---------------- alejandro-alvarez-sonarsource wrote:
Done. https://github.com/llvm/llvm-project/pull/155855 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits