diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1731,8 +1731,8 @@ SkippedChecks.set(SanitizerKind::Null, nullCheck); EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(), - result.getPointer(), allocType, result.getAlignment(), - SkippedChecks, numElements); + result.getPointer(), allocType, allocAlign, SkippedChecks, + numElements); EmitNewInitializer(*this, E, allocType, elementTy, result, numElements, allocSizeWithoutCookie); diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/global-new-alignment.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/global-new-alignment.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/global-new-alignment.cpp @@ -0,0 +1,34 @@ +// RUN: %clangxx -fsanitize=alignment %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not="runtime error" -allow-empty +// Disable with msan and tsan because they also override global new +// UNSUPPORTED: ubsan-msan, ubsan-tsan + +#include +#include +#include + +void *operator new(std::size_t count) { + constexpr const size_t offset = 8; + + // allocate a bit more so we can safely offset it + void *ptr = std::malloc(count + offset); + + // verify malloc returned 16 bytes aligned mem + static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ == 16, + "Global new doesn't return 16 bytes aligned memory!"); + assert(((std::ptrdiff_t)ptr & (__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1)) == 0); + + return (char *)ptr + offset; +} + +struct Param { + void *_cookie1; + void *_cookie2; +}; + +static_assert(alignof(Param) == 8, "Param struct alignment must be 8 bytes!"); + +int main() { + // CHECK-NOT: runtime error: constructor call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'Param', which requires 16 byte alignment + Param *p = new Param; +}