[clang] MSan: poison the default-init allocation before calling constructors (PR #188001)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 23 05:48:38 PDT 2026


https://github.com/dingxiangfei2009 updated https://github.com/llvm/llvm-project/pull/188001

>From 8f08af643f6559fe75adbfa5417b9f98febb17ba Mon Sep 17 00:00:00 2001
From: Xiangfei Ding <dingxiangfei2009 at protonmail.ch>
Date: Thu, 19 Mar 2026 16:04:41 +0000
Subject: [PATCH] MSan: poison the default-init allocation before calling
 constructors

This change is to align with the standards pertaining to reserved global
placement `new`s in the default initialisation style.


Signed-off-by: Xiangfei Ding <dingxiangfei2009 at protonmail.ch>
---
 clang/lib/CodeGen/CGExprCXX.cpp               |  7 ++++
 clang/test/CodeGenCXX/new.cpp                 |  2 +
 .../test/CodeGenCXX/sanitize-default-init.cpp | 38 +++++++++++++++++++
 3 files changed, 47 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/sanitize-default-init.cpp

diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 82300c3ede183..f87b61cbfe163 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -17,8 +17,11 @@
 #include "CodeGenFunction.h"
 #include "ConstantEmitter.h"
 #include "TargetInfo.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/Sanitizers.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Intrinsics.h"
 
 using namespace clang;
@@ -1611,6 +1614,10 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
       allocatorArgs.add(RValue::get(allocation, *this), arg->getType());
     }
 
+    if (E->getInitializationStyle() == CXXNewInitializationStyle::None) {
+      Builder.CreateStore(llvm::PoisonValue::get(ConvertTypeForMem(allocType)),
+                          allocation);
+    }
   } else {
     const FunctionProtoType *allocatorType =
         allocator->getType()->castAs<FunctionProtoType>();
diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp
index af225529c494e..a1a4ad93c9076 100644
--- a/clang/test/CodeGenCXX/new.cpp
+++ b/clang/test/CodeGenCXX/new.cpp
@@ -223,6 +223,7 @@ namespace test15 {
   // CHECK:      [[P:%.*]] = load ptr, ptr
   // CHECK-NOT:  icmp eq ptr [[P]], null
   // CHECK-NOT:  br i1
+  // CHECK-NEXT: store %{{.+}} poison, ptr [[P]]
   // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A:.*]], ptr [[P]], i64 5
   // CHECK-NEXT: br label
   // CHECK:      [[CUR:%.*]] = phi ptr [ [[P]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
@@ -257,6 +258,7 @@ namespace test15 {
   // CHECK:      [[N:%.*]] = load i32, ptr
   // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64
   // CHECK-NEXT: [[P:%.*]] = load ptr, ptr
+  // CHECK-NEXT: store %{{.+}} poison, ptr [[P]]
   // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0
   // CHECK-NEXT: br i1 [[ISEMPTY]],
   // CHECK:      [[END:%.*]] = getelementptr inbounds [[A]], ptr [[P]], i64 [[T0]]
diff --git a/clang/test/CodeGenCXX/sanitize-default-init.cpp b/clang/test/CodeGenCXX/sanitize-default-init.cpp
new file mode 100644
index 0000000000000..191c348e07ceb
--- /dev/null
+++ b/clang/test/CodeGenCXX/sanitize-default-init.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -x c++ -fsanitize=memory -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+/// Sanitise the placement new with default initialisation style.
+
+namespace std {
+    using size_t = decltype(sizeof(0));
+}
+
+void *operator new(std::size_t, void *p) noexcept { return p; }
+
+struct Simple {
+    int x;
+};
+
+struct WithCtor {
+    int x;
+    WithCtor() {
+        bool flag = x > 0; /// This is UB
+    }
+};
+
+// CHECK-LABEL: define {{.*}} i32 @main()
+int main() {
+    {
+        Simple s;
+        s.x = 42;
+        // CHECK: store %struct.Simple poison,
+        new (&s) Simple;
+        bool flag = s.x == 42; /// This is UB
+    }
+    {
+        WithCtor w;
+        w.x = 42;
+        // CHECK: store %struct.WithCtor poison,
+        auto *ptr = new (&w) WithCtor; /// This is UB
+        // CHECK: call void @_ZN8WithCtorC1Ev
+    }
+}



More information about the cfe-commits mailing list