[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #5 from David Greene greened at obbligato dot org --- (In reply to Jonathan Wakely from comment #4) Clang uses the same registers as GCC: Ok, but that still doesn't explain why. Can you point me to wording in either the x86-64 ABI or Itanium ABI that describes this behavior? I have looked for days and can't find anything that suggests this is correct code. Everything I've read points to (RAX, RDX) being the correct return value location. The fact that the Intel compiler disagrees with gcc and clang at least means there is some disagreement on this. This is an interoperability issue and it would be good to get clarity on this so people know what to expect. If gcc and clang are correct that's fine but I would like to know why. Because either gcc and clang have to be fixed or the Intel compiler has to be fixed.
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #6 from David Greene greened at obbligato dot org --- Bug filed against clang to see what they have to say. http://llvm.org/bugs/show_bug.cgi?id=19675
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #8 from David Greene greened at obbligato dot org --- (In reply to H.J. Lu from comment #7) It is the matter of if the size of --- struct B { }; struct X : public B { long p; }; --- is size of long or not. I don't understand. The class of concern is Y, not X. Y is (correctly) 16 bytes, as reported by sizeof(). X is 8 bytes due to EBO. According to my reading of the ABI, a 16-byte struct should be returned in (RAX, RDX).
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #10 from David Greene greened at obbligato dot org --- (In reply to H.J. Lu from comment #9) Y is returned as {NO_CLASS, INTEGER} in register. psABI doesn't explicitly say how NO_CLASS should be handled in this case. GCC simply skips NO_CLASS when assigning it to a register. Except section 3.2.3 when talking about classifying aggregates says under point 4 (b): If one of the classes is NO_CLASS, the resulting class is the other class. So Y should be classified as INTEGER and returned in (RAX, RDX).
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #12 from David Greene greened at obbligato dot org --- (In reply to H.J. Lu from comment #11) That is correct and Y is classified as INTEGER with 2 fields: NO_CLASS, INTEGER. The question is how NO_CLASS should be handled. Since the Returning of Values section of 3.2.3 doesn't talk about aggregate members, I assume that the entire type classification (INTEGER in this case) should be used. That is the interpretation Intel seems to use. The example given does talk about members so I can see how either interpretation could be considered correct. g++ appears to pass such an object in RDI only so it is at least consistent in its pass/return processing. Strangely, icc appears to pass Y in memory!
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #13 from David Greene greened at obbligato dot org --- I see that 3.2.3 4 (b) is talking about considering adjacent fields in an eightbyte. Is the intent to classify each eightbyte in an aggregate and then consider each eightbyte separately for assigning argument and return registers? The post-merger cleanup described in 5 appears to handle passing in memory in that it considers all of the fields in the aggregate together. Given the above, if a field crosses an eightbyte either it is larger than an eightbyte either it is unaligned which forces the whole argument to memory or its eightbytes are classified separately in a recursive manner. Does this sound correct? If so, I think gcc is correct in what it's doing.
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #15 from David Greene greened at obbligato dot org --- (In reply to H.J. Lu from comment #14) I think GCC is correct. I agree. Thanks for working through the explanation with me.
[Bug c++/61082] New: [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 Bug ID: 61082 Summary: [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: greened at obbligato dot org Created attachment 32745 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=32745action=edit Testcase gcc appears to use the wrong sequence for returning an object with head padding. For the attached testcase, gcc -O2 generates the following code for function foo: .globl_Z3fooR1Y .type_Z3fooR1Y, @function _Z3fooR1Y: .LFB1019: .cfi_startproc movq8(%rdi), %rax ret .cfi_endproc The class Y should be classified INTEGER under the x86-64 ABI. It has eight bytes of head padding because it inherits from an empty base class and has a member that also inherits from the same empty base class. By my reading of the ABI, foo should return the Y object in (RAX, RDX), with RDX containing the meaningful bits (the long value). The Intel compiler generates the code I would expect for this testcase.
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #1 from David Greene greened at obbligato dot org --- This is on Linux/SuSE/SLES 11.
[Bug c++/61082] [x86-64 Itanium ABI] g++ uses wrong return location for class with head padding
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61082 --- Comment #3 from David Greene greened at obbligato dot org --- (In reply to Andrew Pinski from comment #2) Y is a non-POD. So...? The ABI doesn't talk about POD vs. non-POD. It talks about copy constructors and destructors. Can you explain what POD has to do with this and why Intel generates the return value in (RAX, RDX)?
[Bug c++/55881] #pragma GCC diagnostic ignored ignored when inlining
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55881 --- Comment #3 from David Greene greened at obbligato dot org 2013-01-07 21:49:58 UTC --- (In reply to comment #1) What is the output of GCC? warning.cpp: In function 'int main(int, char**)': warning.cpp:5:19: warning: 'n' may be used uninitialized in this function [-Wmaybe-uninitialized] warning.cpp:13:16: note: 'n' was declared here
[Bug c++/55881] #pragma GCC diagnostic ignored ignored when inlining
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55881 --- Comment #4 from David Greene greened at obbligato dot org 2013-01-07 21:50:51 UTC --- (In reply to comment #2) Well - confirmed. Unlikely to be fixed. That's _very_ unfortunate. It makes the pragma almost useless in practice.
[Bug c++/55881] New: #pragma GCC diagnostic ignored ignored when inlining
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55881 Bug #: 55881 Summary: #pragma GCC diagnostic ignored ignored when inlining Classification: Unclassified Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: gree...@obbligato.org The following testcase causes g++ 4.7.1 to emit a warning even though it contains a pragma to ignore uninitialized variables. struct I { int i; int foo(struct I *n) { // Warning points here. return n-i + 10; } I(void) : i(5) {} }; int main(int argc, char **) { struct I i, *n; if (argc 10) { n = new I; // Fine. i.i = i.foo(n); } if (argc 2) { #pragma GCC diagnostic ignored -Wmaybe-uninitialized // Still get a warning. return i.foo(n); #pragma GCC diagnostic pop } return 0; } This is the shortest testcase I could produce to demonstrate the problem. I have seen this kind of problem when passing what gcc things are possibly uninitialized variables as arguments to functions which are inlined. Adding a pragma inside the inlined function suppresses the warning but that's a much bigger hammer than placing the pragma around the call site. I do not want to miss possible errors in other contexts where the function is called.
[Bug c/45600] New: gcc generates illegal AVX aligned moves
For the attached testcase, gcc generates a vmovapd for the store to llvm_cbe__24__StackDv_P53. The latest Intel sde generates an alignment error: SDE ERROR: ALIGN32 FAILED PC=40048b MEMEA=7ff057d0 vmovapd ymmword ptr [rax], ymm0 It looks like gcc is considering 16-byte aligned data to be suitable for a 256-bit vmovapd, which it isn't. -- Summary: gcc generates illegal AVX aligned moves Product: gcc Version: 4.5.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: greened at obbligato dot org GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug c/45600] gcc generates illegal AVX aligned moves
--- Comment #1 from greened at obbligato dot org 2010-09-08 16:08 --- Compile with -c -mavx reduced.c. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug c/45600] gcc generates illegal AVX aligned moves
--- Comment #2 from greened at obbligato dot org 2010-09-08 16:09 --- Created an attachment (id=21740) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21740action=view) Reduced testcase -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug target/45600] gcc generates illegal AVX aligned moves
--- Comment #5 from greened at obbligato dot org 2010-09-08 18:52 --- Why is the code undefined? Can you explain in terms of the original test source? I don't immediately see anything undefined there. -- greened at obbligato dot org changed: What|Removed |Added CC||greened at obbligato dot org Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug target/45600] gcc generates illegal AVX aligned moves
--- Comment #7 from greened at obbligato dot org 2010-09-08 18:58 --- (In reply to comment #5) Why is the code undefined? Can you explain in terms of the original test source? I don't immediately see anything undefined there. Ah, the cast from int field5 to v4df? Yes, that doesn't look right to me. Is this what you're talking about? It seems to me that gcc should emit a warning about this and/or not assume that field5 is aligned to 32 bytes, as there is nothing in the source specifying such alignment. If it's an illegal program, gcc should at least emit a warning, if not an error. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug target/45600] gcc generates illegal AVX aligned moves
--- Comment #8 from greened at obbligato dot org 2010-09-08 18:59 --- (In reply to comment #6) The alignment of llvm_cbe__24__StackDv_P53 is only 64bits so you are casting to a greater aligned type and then dereferencing it. I didn't know that typing something as a vector guaranteed alignment. I don't see anything in the gcc manual about that. Isn't that why we have __attribute(aligned())__? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug target/45600] gcc generates illegal AVX aligned moves
--- Comment #11 from greened at obbligato dot org 2010-09-08 19:16 --- (In reply to comment #9) If it's an illegal program, gcc should at least emit a warning, if not an error. It is not an invalid program, Yes, you are quite right. I will take this up with the LLVM folks. :) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45600
[Bug libstdc++/35969] New: GLIBCXX_DEBUG: list::merge triggers bad assert
The attached preprocessed source when compiled with -D_GLIBCXX_DEBUG encounters a runtime assert at the final call to splice. According to http://www.sgi.com/tech/stl/List.html, all iterators remain valid after a merge operation. I believe that libstdc++ is not updating the _M_sequence members of the safe iterators merged into list1. I've also attached unpreprocessed source with comments indicating the problem. To reproduce the problem: % g++ -D_GLIBCXX_DEBUG list.ii % ./a.out /usr/include/c++/4.2/debug/list:350:error: attempt to splice an iterator from a different container. Objects involved in the operation: iterator __i @ 0x0xbfd5ea30 { type = N11__gnu_debug14_Safe_iteratorINSt6__norm14_List_iteratorIiEENSt7__debug4listIiSaIiE (mutable iterator); state = dereferenceable; references sequence with type `NSt7__debug4listIiSaIiEEE' @ 0x0xbfd5ea30 } sequence __x @ 0x0xbfd5e9c4 { type = NSt7__debug4listIiSaIiEEE; } Aborted -- Summary: GLIBCXX_DEBUG: list::merge triggers bad assert Product: gcc Version: 4.2.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: greened at obbligato dot org GCC build triplet: i486-linux-gnu GCC host triplet: i486-linux-gnu GCC target triplet: i486-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35969
[Bug libstdc++/35969] GLIBCXX_DEBUG: list::merge triggers bad assert
--- Comment #1 from greened at obbligato dot org 2008-04-18 03:12 --- Created an attachment (id=15493) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15493action=view) Preprocessed source -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35969
[Bug libstdc++/35969] GLIBCXX_DEBUG: list::merge triggers bad assert
--- Comment #2 from greened at obbligato dot org 2008-04-18 03:13 --- Created an attachment (id=15494) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15494action=view) Unpreprocessed source Includes comments describing the problem. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35969
[Bug libstdc++/35969] GLIBCXX_DEBUG: list::merge triggers bad assert
--- Comment #4 from greened at obbligato dot org 2008-04-18 03:26 --- Subject: Re: GLIBCXX_DEBUG: list::merge triggers bad assert pinskia at gcc dot gnu dot org wrote: --- Comment #3 from pinskia at gcc dot gnu dot org 2008-04-18 03:23 --- I don't know if the SGI website has been updated to take into account what the C++ standard says. Since STL was originally from HP/SGI, that page is old and might not reflect reality any more. Sure. But not everyone has a copy of the standard. :) Can we get a ruling on this? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35969
[Bug libstdc++/35969] GLIBCXX_DEBUG: list::merge triggers bad assert
--- Comment #5 from greened at obbligato dot org 2008-04-18 04:16 --- Ok, the closest thing I could find is the 1998 draft standard: http://www.kuzbass.ru:8086/docs/isocpp/lib-containers.html#lib.sequences It says that splice invalidates only the iterators and references to the spliced elements. There is no statement about iterators for merge. So it seems like the testcase is invalid not due to the merge but due to the splices. GLIBCXX_DEBUG mode doesn't catch the problem with the splices since the iterator is still considered valid after the splice. For example, the second splce doesn't assert on an invalid iterator being passed to it. Perhaps this was changed in the final standard. It seems odd to me that splice and merge would invalidate iterators as iterator stability is a prime reason for using std::list and these operations don't destroy any sequence values. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35969
[Bug c++/32346] long long bitfield passed to int argument incorrectly
--- Comment #4 from greened at obbligato dot org 2007-07-25 19:47 --- It is also broken on trunk. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32346
[Bug c++/32346] long long bitfield passed to int argument incorrectly
--- Comment #3 from greened at obbligato dot org 2007-07-24 19:59 --- This is also broken in 4.2.1. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32346
[Bug c++/32346] New: long long bitfield passed to int argument incorrectly
A long long bitfield of size 32 is passed to a function taking an int argument using two argument slots. Adding an explicit cast solves the problem. Testcase: #include stdio.h typedef struct { long long item : 32; } tester; void dosomething(int i, int j) { printf(i = %#x, j = %#x\n, i, j); } void foo(tester bar) { dosomething(bar.item, 0); } int main(void) { tester test; test.item = 0xabcdef01; foo(test); return(0); } Asm: .align 2 .globl _Z3foo6tester .type _Z3foo6tester, @function _Z3foo6tester: .LFB3: pushl %ebp .LCFI3: movl%esp, %ebp .LCFI4: subl$24, %esp .LCFI5: movl8(%ebp), %eax movl%eax, %edx sarl$31, %edx movl$0, 8(%esp) movl%eax, (%esp) movl%edx, 4(%esp) call_Z11dosomethingii leave ret .LFE3: .size _Z3foo6tester, .-_Z3foo6tester Output: i = 0xabcdef01, j = 0x With explicit cast: void foo(tester bar) { dosomething((int)bar.item, 0); } Asm: .align 2 .globl _Z3foo6tester .type _Z3foo6tester, @function _Z3foo6tester: .LFB3: pushl %ebp .LCFI3: movl%esp, %ebp .LCFI4: subl$8, %esp .LCFI5: movl8(%ebp), %eax movl$0, 4(%esp) movl%eax, (%esp) call_Z11dosomethingii leave ret .LFE3: .size _Z3foo6tester, .-_Z3foo6tester Output: i = 0xabcdef01, j = 0 -- Summary: long long bitfield passed to int argument incorrectly Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: greened at obbligato dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32346
[Bug c++/32346] long long bitfield passed to int argument incorrectly
--- Comment #1 from greened at obbligato dot org 2007-06-14 20:48 --- Created an attachment (id=13705) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=13705action=view) Preprocessed testcase -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32346
[Bug c++/32346] long long bitfield passed to int argument incorrectly
--- Comment #2 from greened at obbligato dot org 2007-06-14 20:50 --- Configuration: g++ -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: /tools/gcc-4.2.0/configure --prefix=/tools/i686-pc-linux-gnu --disable-shared --with-gnu-as --with-gnu-ld --with-build-time-tools=/tools/i686-pc-linux-gnu/bin --with-mpfr=/tools/i686-pc-linux-gnu --with-gmp=/tools/i686-pc-linux-gnu --enable-targets=all Thread model: posix gcc version 4.2.0 This only fails with g++. gcc compiles it fine. -- greened at obbligato dot org changed: What|Removed |Added CC||greened at obbligato dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32346