<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 13 February 2017 at 06:55, Stephan Bergmann <span dir="ltr"><<a href="mailto:sbergman@redhat.com" target="_blank">sbergman@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Since r283789 (re-commit of r283722, "P0035R4: Semantic analysis and code generation for C++17 overaligned allocation"), CodeGenFunction::EmitCXXNewExp<wbr>r (lib/CodeGen/CGExprCXX.cpp) contains<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
    // If this was a call to a global replaceable allocation function that does<br>
    // not take an alignment argument, the allocator is known to produce<br>
    // storage that's suitably aligned for any object that fits, up to a known<br>
    // threshold. Otherwise assume it's suitably aligned for the allocated type.<br>
    CharUnits allocationAlign = allocAlign;<br>
    if (!E->passAlignment() &&<br>
        allocator->isReplaceableGlobal<wbr>AllocationFunction()) {<br>
      unsigned AllocatorAlign = llvm::PowerOf2Floor(std::min<u<wbr>int64_t>(<br>
          Target.getNewAlign(), getContext().getTypeSize(alloc<wbr>Type)));<br>
      allocationAlign = std::max(<br>
          allocationAlign, getContext().toCharUnitsFromBi<wbr>ts(AllocatorAlign));<br>
    }<br>
</blockquote>
<br>
which I have two questions about:<br>
<br>
*  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<br>
to a pointer of any complete object type with a fundamental alignment requirement", [basic.stc.dynamic.allocation]<wbr>), and that P0035R4 (presumably unintentionally) makes it confusing that this consistency still holds (cf. my question at <<a href="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-discussion/mTZ4sB5P1Sg" rel="noreferrer" target="_blank">https://groups.google.com/a/i<wbr>socpp.org/forum/?fromgroups#!t<wbr>opic/std-discussion/mTZ4sB5P1S<wbr>g</a>> "Confusing wording in P0035R4, 'any suitable complete object type'").<br></blockquote><div><br></div><div>There is no reasonable assumption you can make about the alignment provided by any other 'operator new' function, other than assuming that the user got it right: that it produces a pointer that is suitably aligned for the allocated object. For instance, a class-specific allocator for a class with 1-byte alignment might reasonably produce 1-byte-aligned pointers regardless of the allocation size. Breaking such code merely because poor wording in the C++ standard may have allowed us to do so seems unlikely to make anyone happier.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
*  At least with the wording from P0035R4, it is unclear to me what the alignment requirements in<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
struct S { char a[25]; };<br>
S * func() { return new S(); }<br>
</blockquote>
<br>
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.</blockquote><div><br></div><div>Yes, you're right that this is at best unclear and at worst says that our assumption is not valid for allocations that are not a multiple of the allocator alignment. This is the subject of C++ core issue 2207 (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2207">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2207</a>, but there's no information on the public version of the issues list yet); there generally seemed to be consensus in committee discussion that global non-array non-aligned operator new should provide sufficient storage for any object with a fundamental alignment that fits in the storage, not just for fundamental alignments that divide the allocated size.</div><div><br></div><div>For instance, we want to guarantee that this sort of thing works:</div><div><br></div><div>S *p = func();</div><div>static_assert(sizeof(long double) <= 25);</div><div>new (p->a) long double; // ok, 'a' is suitably aligned for 'long double'</div><div><br></div><div>Is this assumption causing problems in practice?</div></div></div></div>