[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32

2024-06-28 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2018-11-20 Thread foom at fuhm dot net
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

2018-04-26 Thread peter at cordes dot ca
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

2018-04-24 Thread jason at gcc dot gnu.org
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

2018-04-23 Thread jason at gcc dot gnu.org
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

2018-04-19 Thread joseph at codesourcery dot com
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

2018-04-11 Thread jason at gcc dot gnu.org
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

2018-04-10 Thread hjl.tools at gmail dot com
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

2018-04-10 Thread jason at gcc dot gnu.org
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

2018-04-10 Thread jason at gcc dot gnu.org
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

2016-07-20 Thread sch...@linux-m68k.org
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

2016-07-20 Thread mh+gcc at glandium dot org
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

2016-07-20 Thread sch...@linux-m68k.org
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

2016-07-20 Thread mh+gcc at glandium dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560

Mike Hommey  changed:

   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

2016-01-30 Thread redi at gcc dot gnu.org
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

2016-01-30 Thread redi at gcc dot gnu.org
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

2016-01-29 Thread redi at gcc dot gnu.org
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

2016-01-29 Thread redi at gcc dot gnu.org
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

2016-01-29 Thread pinskia at gcc dot gnu.org
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

2016-01-29 Thread pinskia at gcc dot gnu.org
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

2016-01-29 Thread david.merillat at gmail dot com
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

2016-01-29 Thread david.merillat at gmail dot com
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

2016-01-29 Thread pinskia at gcc dot gnu.org
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

2016-01-29 Thread redi at gcc dot gnu.org
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

2016-01-29 Thread joseph at codesourcery dot com
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.