[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #25 from GCC Commits --- The master branch has been updated by Jonathan Wakely : https://gcc.gnu.org/g:ac8c61b62e71ffdcaebfd4cfc03f58fe542855dd commit r15-1713-gac8c61b62e71ffdcaebfd4cfc03f58fe542855dd Author: Jonathan Wakely Date: Wed Jun 26 12:40:51 2024 +0100 libstdc++: Simplify class templates As noted in a comment, the __gnu_cxx::__aligned_membuf class template can be simplified, because alignof(T) and alignas(T) use the correct alignment for a data member. That's true since GCC 8 and Clang 8. The EDG front end (as used by Intel icc, aka "Intel C++ Compiler Classic") does not implement the PR c++/69560 change, so keep using the old implementation when __EDG__ is defined, to avoid an ABI change for icc. For __gnu_cxx::__aligned_buffer all supported compilers agree on the value of __alignof__(T), but we can still simplify it by removing the dependency on std::aligned_storage. Add a test that checks that the aligned buffer types have the expected alignment, so that we can tell if changes like this affect their ABI properties. libstdc++-v3/ChangeLog: * include/ext/aligned_buffer.h (__aligned_membuf): Use alignas(T) directly instead of defining a struct and using 9its alignment. (__aligned_buffer): Remove use of std::aligned_storage. * testsuite/abi/aligned_buffers.cc: New test.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #24 from James Y Knight --- Note that I've filed PR88115 and PR88119 for some bugs caused by this change.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Peter Cordes changed: What|Removed |Added CC||peter at cordes dot ca --- Comment #23 from Peter Cordes --- Just to recap the current situation (gcc/g++ 8.0.1 20180425): I ported David Marillat's testcase to work as C or C++ https://godbolt.org/g/QdG2V6. (And changed it to set global variables instead of calling printf, so you can see the results from looking at the asm output instead of running it). C++11 alignof() now agrees with C11 alignof() (which didn't change) that alignof(int64_t) is 4 when targeting the i386 System V ABI. Previously G++'s alignof() reported 8, while gcc's C11 alignof (stdalign.h) reported 4. That was the only change: struct-member alignof results are unchanged, and already matched between C11 and C++11. 4 is the minimum alignment that *any* int64_t, or pointer to int64_t, is assumed to have when generating code for i386 SysV. gcc / g++ are allowed to generate code that breaks if passed a pointer to int64_t that wasn't 4-byte aligned. (Auto-vectorization is one case where that can happen on x86: https://stackoverflow.com/q/47510783/224132). They're *not* allowed to assume that it's 8-byte aligned unless they can see the definition and know that a particular int64_t object is over-aligned, e.g. to its natural alignment of 8, like gcc chooses to do whenever possible (i.e. outside structs). So in both C++ and C (and in g++/gcc after this patch), alignof(int64_t) is the minimum that any allocator must give an int64_t for correctness (in this funky 32-bit ABI), not the recommended alignment that gcc and g++ both already used whenever ABI struct-packing rules didn't constrain them. It's also the guaranteed minimum that code can *assume*. e.g. a manually-vectorized library function might check alignof(T) == sizeof(T) before assuming that using 16-byte aligned loads/stores can line up with element boundaries. (An array inside a struct { int foo; int64_t arr[10]; } would violate this for i386 SysV). Anyway, I think use-cases like these are why the standard is worded the way it is, and why it makes sense for alignof() to report the guaranteed/required minimum. The recommended or actual alignment is useful, too, though, for other cases, so it's nice that GNU __alignof() is also available to report that. Semi-related: gcc depends on 8-byte alignment for C11 _Atomic int64_t but still fails to provide it inside structs on the i386 SysV ABI (Bug 65146), using the same alignment rules as regular int64_t. C++11 std::atomic is fine, getting the required natural alignment even on i386 SysV so SSE2 movq is atomic and lock add is efficient. This change to what alignof() reports in C++ had no effect on C at all, or on any alignment choices made by the compiler in either C or C++. I only mention it as another interesting case where i386 SysV's under-alignment of 64-bit types requiring special care, but that one will require an ABI change of some sort to fix.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Jason Merrill changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED Target Milestone|--- |8.0 --- Comment #22 from Jason Merrill --- Fixed for GCC 8.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #21 from Jason Merrill --- Author: jason Date: Mon Apr 23 20:49:38 2018 New Revision: 259578 URL: https://gcc.gnu.org/viewcvs?rev=259578=gcc=rev Log: PR c++/69560 - wrong alignof(double) on x86. CWG 1879 - Inadequate definition of alignment requirement. * cp-tree.h (ALIGNOF_EXPR_STD_P): New. * typeck.c (cxx_sizeof_or_alignof_type): Add std_alignof parm. (cxx_sizeof_expr, cxx_sizeof_nowarn, cxx_alignas_expr) (cxx_alignof_expr): Pass it. * parser.c (cp_parser_unary_expression): Pass it. * pt.c (tsubst_copy): Copy it. (tsubst_copy_and_build): Pass it. * decl.c (fold_sizeof_expr): Pass it. Added: trunk/gcc/testsuite/g++.dg/abi/align2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/decl.c trunk/gcc/cp/parser.c trunk/gcc/cp/pt.c trunk/gcc/cp/typeck.c trunk/libcc1/libcp1plugin.cc
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #20 from joseph at codesourcery dot com --- I consider it part of the ABI that long long __attribute__((__aligned__(__alignof__(long long, as in the definition of max_align_t (and similarly in gnulib's max_align_t definition, for example), is 8-byte-aligned on x86.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #19 from Jason Merrill --- (In reply to H.J. Lu from comment #18) > (In reply to Jason Merrill from comment #16) > > (In reply to Andreas Schwab from comment #15) > > > Because the ABI says so. > > > > Which ABI? In https://www.uclibc.org/docs/psABI-i386.pdf I see > > > > long long: sizeof 8, alignment 4. > > > > That GCC chooses to give stronger alignment to long long variables isn't > > part of the ABI, and shouldn't affect the value of alignof. > > FYI, x86 psABIs are at > > https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI And those also say that double and long long have alignment 4.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #18 from H.J. Lu --- (In reply to Jason Merrill from comment #16) > (In reply to Andreas Schwab from comment #15) > > Because the ABI says so. > > Which ABI? In https://www.uclibc.org/docs/psABI-i386.pdf I see > > long long: sizeof 8, alignment 4. > > That GCC chooses to give stronger alignment to long long variables isn't > part of the ABI, and shouldn't affect the value of alignof. FYI, x86 psABIs are at https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Jason Merrill changed: What|Removed |Added CC||richard-gccbugzilla@metafoo ||.co.uk --- Comment #17 from Jason Merrill --- *** Bug 69763 has been marked as a duplicate of this bug. ***
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Jason Merrill changed: What|Removed |Added Status|RESOLVED|ASSIGNED Last reconfirmed||2018-04-11 CC||jason at gcc dot gnu.org Resolution|INVALID |--- Assignee|unassigned at gcc dot gnu.org |jason at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #16 from Jason Merrill --- (In reply to Andreas Schwab from comment #15) > Because the ABI says so. Which ABI? In https://www.uclibc.org/docs/psABI-i386.pdf I see long long: sizeof 8, alignment 4. That GCC chooses to give stronger alignment to long long variables isn't part of the ABI, and shouldn't affect the value of alignof.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #15 from Andreas Schwab--- Because the ABI says so.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #14 from Mike Hommey--- (In reply to Andreas Schwab from comment #13) > alignof(long long) "type of a complete object" > alignof(foo) "type of a subobject" But that doesn't tell why the alignment of a long long is 8 as a complete object, but 4 as a subobject (the offset of l in foo is 4, not 8).
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #13 from Andreas Schwab--- alignof(long long) "type of a complete object" alignof(foo) "type of a subobject"
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Mike Hommeychanged: What|Removed |Added CC||mh+gcc at glandium dot org --- Comment #12 from Mike Hommey --- (In reply to Jonathan Wakely from comment #11) > > See Joseph's explanation at: > > https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00435.html > > Which refers to 3.11 [basic.align] p2: > >The alignment required for a type might be different when it is used as > the >type of a complete object and when it is used as the type of a subobject. That doesn't seem to explain why the following is not true when compiling with -m32: struct foo { char c; long long l; }; static_assert(alignof(long long) == alignof(foo), "");
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #11 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #10) > (In reply to David Merillat from comment #8) > > One thing remains. As a result of 52023, C11 _Alignof was "fixed" to return > > the smallest possible alignment, but C++11 was left alone "deliberately", > > although "C++11 will need examining to determine what is right for alignof > > there". I didn't see any such discussion for C++11 or C++14 alignof(), and > > by my reading of the specifications, they are defined almost identically to > > C11 _Alignof. > > See Joseph's explanation at: > https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00435.html Which refers to 3.11 [basic.align] p2: The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #10 from Jonathan Wakely --- (In reply to David Merillat from comment #8) > One thing remains. As a result of 52023, C11 _Alignof was "fixed" to return > the smallest possible alignment, but C++11 was left alone "deliberately", > although "C++11 will need examining to determine what is right for alignof > there". I didn't see any such discussion for C++11 or C++14 alignof(), and > by my reading of the specifications, they are defined almost identically to > C11 _Alignof. See Joseph's explanation at: https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00435.html
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #1 from Jonathan Wakely --- (In reply to David Merillat from comment #0) > I checked the ISO C++ spec, section 3.11, and it says "The alignment > requirement of a complete type can be queried using an alignof expression", > so if alignof(int64_t) yields 8, then it shouldn't be legal to place an > int64_t at offset 4 in a structure. That's not true. Some types have weaker alignment requirements when they are structure members.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #2 from Jonathan Wakely --- See ADJUST_FIELD_ALIGN at https://gcc.gnu.org/onlinedocs/gccint/Storage-Layout.html#Storage-Layout unsigned long long on x86 is such a type.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Andrew Pinski changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE --- Comment #5 from Andrew Pinski --- Dup of bug 10360 (This has been discussed many times). *** This bug has been marked as a duplicate of bug 10360 ***
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 Andrew Pinski changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|DUPLICATE |--- --- Comment #9 from Andrew Pinski --- Reopening as I did not realize this was about C++11's alignof. I had thought it was about GCC's __alignof extension; I should look closer :).
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #8 from David Merillat --- (In reply to Andrew Pinski from comment #6) > Actually bug 52023 is a better reason for the difference between __alignof__ > and _Alignof. > > *** This bug has been marked as a duplicate of bug 52023 *** Yes, that bug dealt with the issue more thoroughly, dealing with the issues I am looking at. I wish I had found it earlier. One thing remains. As a result of 52023, C11 _Alignof was "fixed" to return the smallest possible alignment, but C++11 was left alone "deliberately", although "C++11 will need examining to determine what is right for alignof there". I didn't see any such discussion for C++11 or C++14 alignof(), and by my reading of the specifications, they are defined almost identically to C11 _Alignof. So I think the central issue in this bug remains open. I'll leave it to someone else whether to reopen the case.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #4 from David Merillat --- (In reply to Jonathan Wakely from comment #2) > See ADJUST_FIELD_ALIGN at > https://gcc.gnu.org/onlinedocs/gccint/Storage-Layout.html#Storage-Layout > > unsigned long long on x86 is such a type. Thank you for the pointers into GCC internals, of which I was unaware. However, the C++14 specification makes no mention of weaker alignment requirements for structure members that I could find. In fact, the specification for alignof() in C++14 is remarkably similar to that of _Alignof in C11 (I would assume one is derived from the other. _Alignof yields what I believe to be the correct answer in this case: test2.c #include #include #include int main(void) { printf( "_Alignof(int64_t) = %d\n", _Alignof(int64_t) ); return 0; } ## gcc -std=C11 test2.c -o test2 -m32 ## _Alignof(int64_t) = 4 ##
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #6 from Andrew Pinski --- Actually bug 52023 is a better reason for the difference between __alignof__ and _Alignof. *** This bug has been marked as a duplicate of bug 52023 ***
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #7 from Jonathan Wakely --- (In reply to David Merillat from comment #0) > DefaultStruct s; > printf( "DefaultStruct: offset=%d, struct align=%d, member align=%d, > type align=%d\n", > offsetof(DefaultStruct,i64), alignof(s), alignof(s.i64), > alignof(int64_t) ); N.B. this isn't valid C++ or C, because the operand of alignof must be a type, not an object. So standard C++ doesn't even let you ask for alignof(s.i64), it only lets you ask for the alignment of uint64_t, which for a not-sub-object is 8.
[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 --- Comment #3 from joseph at codesourcery dot com --- This is where C distinguishes C11 _Alignof (the minimum alignment the type is guaranteed to have in all contexts, so 4, see min_align_of_type) from GNU C __alignof (the normal alignment of the type, so 8). I don't know if a similar distinction is needed for C++; that depends on how the standard C++ alignof is specified.