[clang] [analyzer] Improve handling of placement new in `PointerArith` (PR #155855)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 28 09:51:20 PDT 2025
Alejandro =?utf-8?q?Álvarez_Ayllón?Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/155855 at github.com>
================
@@ -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);
----------------
steakhal wrote:
Why do we need to escape these btw?
https://github.com/llvm/llvm-project/pull/155855
More information about the cfe-commits
mailing list