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 <[email protected]> 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 <[email protected]> --- 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 + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
