================
@@ -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

Reply via email to