[clang] [compiler-rt] Ubsan minimum assumed alignment (PR #166755)

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 2 10:32:39 PST 2025


================
@@ -1749,17 +1751,32 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
       allocator->isReservedGlobalPlacementOperator())
     result = Builder.CreateLaunderInvariantGroup(result);
 
+  // Check the default alignment of the type and why. Users may incorrectly
+  // return misaligned memory from a replaced operator new without knowing
+  // about default alignment.
+  TypeCheckKind checkKind = CodeGenFunction::TCK_ConstructorCall;
+  CharUnits checkAlignment = result.getAlignment();
+  const TargetInfo &TI = getContext().getTargetInfo();
+  unsigned DefaultTargetAlignment = TI.getNewAlign() / TI.getCharWidth();
+  if (SanOpts.has(SanitizerKind::Alignment) &&
+      (DefaultTargetAlignment >
+       CGM.getContext().getTypeAlignInChars(allocType).getQuantity()) &&
+      !result.getAlignment().isOne() &&
----------------
efriedma-quic wrote:

The standard language here is: "if the allocation function is named operator new[], the storage is aligned for any object that does not have new-extended alignment and is no larger than the requested size."

Note this means the alignment requirement is lower for very small allocations.  If the allocation size is zero, there is no alignment requirement because no object can fit into the requested size.  Similarly, if the allocation size is two, the alignment requirement is two, because objects with larger alignment requirements can't fit into two bytes.

I think EmitTypeCheck isn't doing the right check, given those rules.

https://github.com/llvm/llvm-project/pull/166755


More information about the llvm-commits mailing list