[cfe-dev] operator new alignment assumptions

Stephan Bergmann via cfe-dev cfe-dev at lists.llvm.org
Mon Feb 13 06:55:55 PST 2017


Since r283789 (re-commit of r283722, "P0035R4: Semantic analysis and 
code generation for C++17 overaligned allocation"), 
CodeGenFunction::EmitCXXNewExpr (lib/CodeGen/CGExprCXX.cpp) contains

>     // If this was a call to a global replaceable allocation function that does
>     // not take an alignment argument, the allocator is known to produce
>     // storage that's suitably aligned for any object that fits, up to a known
>     // threshold. Otherwise assume it's suitably aligned for the allocated type.
>     CharUnits allocationAlign = allocAlign;
>     if (!E->passAlignment() &&
>         allocator->isReplaceableGlobalAllocationFunction()) {
>       unsigned AllocatorAlign = llvm::PowerOf2Floor(std::min<uint64_t>(
>           Target.getNewAlign(), getContext().getTypeSize(allocType)));
>       allocationAlign = std::max(
>           allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign));
>     }

which I have two questions about:

*  Why restrict this to global replaceable allocation functions?  My 
interpretation of the standard up to C++14 is that all allocation 
functions consistently have the same requirements wrt alignment ("The 
pointer returned shall be suitably aligned so that it can be converted
to a pointer of any complete object type with a fundamental alignment 
requirement", [basic.stc.dynamic.allocation]), and that P0035R4 
(presumably unintentionally) makes it confusing that this consistency 
still holds (cf. my question at 
<https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-discussion/mTZ4sB5P1Sg> 
"Confusing wording in P0035R4, 'any suitable complete object type'").

*  At least with the wording from P0035R4, it is unclear to me what the 
alignment requirements in

> struct S { char a[25]; };
> S * func() { return new S(); }

are.  When compiled at -O for x86_64-unknown-linux-gnu, Clang trunk 
apparently assumes that the pointer returned from operator new is 
16-byte aligned (writing to it with movaps).  But the requirements for 
that operator new in [new.delete.single] merely states that it 
"allocates storage suitably aligned to represent any object of that 
size", and I don't think there is a type of size 25 with a stricter 
alignment requirement than 1 for that target.



More information about the cfe-dev mailing list