[Bug libstdc++/88466] [C++17] Support std::hardware_destructive_interference_size and std:: hardware_constructive_interference_size
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88466 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #7 from James Y Knight --- FWIW, the discussion in Clang about this is still ongoing, and the functions remain unimplemented there. I personally remain of the opinion that it would be ideal to leave these permanently unimplemented, despite that the standards committee decided to keep them in the standard even after objections were raised. My second-favorite implementation after "unimplemented", would be to just return constant values of 64 and 128 universally, regardless of architecture. (If you cannot return an actually-correct answer, and decided that you need to return something, you might as well just do something really easy and, _shrug_, oh well.). Others are arguing for implementing them to return actually valid and correct values that depend on the exact configuration, and marking them as not being abi-stable. Users would then need to be aware that they must not use the constants in ABIs (which means effectively "don't use in a header file"), since the value might change at any time with a compiler upgrade, or with the use of different command-line flags (e.g. -mcpu/-march). (To return correct values, compiler upgrades must be allowed to change the values if it becomes aware of a new CPU model which changes the largest/smallest-known cacheline sizes that this code could run on. And -mcpu/-march flags similarly ought to change the values by restricting the possible set of CPUs this code might run on.) Any new thoughts from GCC developers?
[Bug libstdc++/89855] Inconsistent global namespace overload sets from #include
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855 --- Comment #6 from James Y Knight --- Someone has pointed out to me that the standard actually says "name", which I had internalized as meaning "declaration", but it doesn't. This arguably does make the GCC implementation non-compliant with the spec. >From http://eel.is/c++draft/headers#5 > Except as noted in [library] through [thread] and [depr], the contents of > each header cname is the same as that of the corresponding header name.h as > specified in the C standard library. In the C++ standard library, however, > the declarations (except for names which are defined as macros in C) are > within namespace scope of the namespace std. It is unspecified whether these > names (including any overloads added in [support] through [thread] and > [depr]) are first declared within the global namespace scope and are then > injected into namespace std by explicit using-declarations. I think that text implies that all of the overloads of a particular name must consistently either be defined in the global namespace (and then imported into std with a using-declaration) or defined in the std namespace.
[Bug libstdc++/89855] Inconsistent global namespace overload sets from #include
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855 --- Comment #7 from James Y Knight --- Ugh, GCC doesn't wrap quoted text? Re-posting the quote from http://eel.is/c++draft/headers#5 without a quote marker... """ Except as noted in [library] through [thread] and [depr], the contents of each header cname is the same as that of the corresponding header name.h as specified in the C standard library. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope of the namespace std. It is unspecified whether these names (including any overloads added in [support] through [thread] and [depr]) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations. """
[Bug target/95722] libatomic crashes on __atomic_load of const object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95722 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #1 from James Y Knight --- The fix would be to have libatomic use a lock instead of the lock-free cmpxchg16b instruction to implement atomic_load. But I think this is impossible without causing incompatibility with older GCCs. Older versions of GCC (before GCC 7), and Clang to this day, emitted cmpxchg16b inline for a 16-byte atomic load when you compile with -mcx16. And thus, unfortunately, I think if libatomic switched to a lock now, it would not be compatible with those older programs.
[Bug libstdc++/54172] [4.7/4.8 Regression] __cxa_guard_acquire thread-safety issue
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54172 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #3 from James Y Knight 2012-08-30 02:39:31 UTC --- Ping; this seems like a serious regression in 4.7 with a patch. I guess fixing it is blocked on Thiago posting the patch to gcc-patches?
[Bug libstdc++/54075] [4.7.1] unordered_map insert 3x slower than 4.6.2
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54075 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #34 from James Y Knight 2012-11-04 04:55:30 UTC --- Well, I haven't looked into this issue in detail, but, it looks like everyone is about the same speed if you put a foo.{reserve or rehash}(n) before the inserts. Unfortunately, it doesn't look as simple as the new impl calling for a rehash more often than the old, cause it's not. So, I don't know if the slowness is because rehash is now a lot slower, or if insert is slower but only if there aren't a huge number of empty buckets. I'll also note that libc++'s implementation (seen here: http://llvm.org/svn/llvm-project/libcxx/trunk/) appears to be getting the same speed as the old libstdc++ implementation, while appearing to have approximately the same bucket datastructure as the new libstdc++ implementation. That says to me that it should be *possible* somehow to make the new version fast.
[Bug c++/41863] New: [4.5 Regression] segfault with sizeof in template parameter
GCC 4.5 appears to fail when using sizeof(member-of-templated-type) inside a template parameter. I have tested the Debian gcc-snapshot 20090923-1 amd64 package, 20091010-1 i386, and Ubuntu gcc-snapshot 20091018-1 amd64. All exhibit the same behavior. g++-4.4 works fine, however. Changing to "sizeof(m_foo)" to "sizeof(T)" also fixes the problem. File /tmp/test.cpp: ===CUT=== template struct Bar { }; template class Foo { T m_foo; void crash() { Bar bar; } }; ===CUT=== $ g++ -c /tmp/test.cpp /tmp/test.cpp: In member function 'void Foo::crash()': /tmp/test.cpp:8:26: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See for instructions. -- Summary: [4.5 Regression] segfault with sizeof in template parameter Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: foom at fuhm dot net GCC host triplet: x86_64-linux-gnu GCC target triplet: x86_64-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41863
[Bug middle-end/41290] [4.5 regression] C++ - libdirac don't want to compile
--- Comment #5 from foom at fuhm dot net 2009-10-30 02:42 --- An error very much like this is also causing a bunch of files in my program to fail to compile with 4.5 with -O1 and above. I was unable to reduce a simple test case from my (private) code, though: many changes that seem like they should be unrelated cause the bug to go away. So I really hope my bug is actually the same thing as this already-somewhat-reduced test case. :) I'm using the ubuntu gcc-snapshot 20091018 package, on x86-64. The error message is a little bit different, so I'm including it below, just in case you might think it indicates a different underlying cause. error: edge points to wrong declaration: > QI size unit size align 8 symtab 0 alias set -1 canonical type 0x2ab09e701240 method basetype arg-types chain >> pointer_to_this > addressable used nothrow static in_system_header autoinline decl_5 QI defer-output file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 7 align 16 context initial abstract_origin arguments readonly unsigned DI size unit size align 64 symtab -1364669056 alias set -1 canonical type 0x2ab09e6fdcc0> readonly used unsigned DI file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 23 size unit size align 64 context abstract_origin arg-type > result used ignored VOID file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 27 align 8 context abstract_origin > full-name "std::basic_iostream<_CharT, _Traits>::~basic_iostream() [with _CharT = char, _Traits = std::char_traits]" pending-inline-info 0x2ab0ab72f000 template-info 0x2ab09e6faf90 struct-function 0x2ab0ab58f6e0> Instead of: > QI size unit size align 8 symtab 0 alias set -1 canonical type 0x2ab09e701240 method basetype arg-types chain chain >>> pointer_to_this > addressable used nothrow public static external in_system_header autoinline decl_5 QI defer-output file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 7 align 16 context initial abstract_origin arguments readonly unsigned DI size unit size align 64 symtab -1364669056 alias set -1 canonical type 0x2ab09e6fdcc0> readonly unsigned DI file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 23 size unit size align 64 context abstract_origin arg-type chain readonly unsigned DI file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 7 size unit size align 64 context abstract_origin arg-type >> result ignored VOID file /usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream line 798 col 27 align 8 context > full-name "std::basic_iostream<_CharT, _Traits>::~basic_iostream() [with _CharT = char, _Traits = std::char_traits]" pending-inline-info 0x2ab0ab72f000 template-info 0x2ab09e6faf90 struct-function 0x2ab0ab71ed20 chain > -- foom at fuhm dot net changed: What|Removed |Added ---------------- CC||foom at fuhm dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290
[Bug c++/54170] Call to lambda elided
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54170 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #13 from James Y Knight --- Possibly should be backported to 4.7 branch?
[Bug libstdc++/49561] [C++0x] std::list::size complexity
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561 foom at fuhm dot net changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #8 from foom at fuhm dot net 2011-10-07 01:26:28 UTC --- This change seems like it might be the first major incompatibility added to gcc's c++0x mode (at least, things appeared to work before, maybe that was just luck). I guess it will now be dangerous to even load a shared lib compiled with --std=c++0x into the same executable as C++ code compiled in the default c++03 mode, because of the potential for the exported weak symbols from out-of-line std::list functions compiled for one layout to be used on a structure defined with the other layout in the other shared object. Even when no c++ objects are ever passed from one shared lib to the other. This seems like a particularly bad failure mode to have, especially considering also bug 36022 (invalid), since it's by design difficult to *not* export the symbols even if you try. I understand that the versioned namespaces feature is supposed to help with this sort of issue; is there any plan to use it to give the c++0x std::list object a different mangled name than the c++03 std::list object?
[Bug c++/53356] New: ICE in verify_gimple_stmt, at tree-cfg.c:4258
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53356 Bug #: 53356 Summary: ICE in verify_gimple_stmt, at tree-cfg.c:4258 Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: f...@fuhm.net On the code: test.cpp: === class A {}; struct B { operator const A &() const; }; A* cause_ICE() { return new A(B()); } === Running: g++ -std=c++0x -c test.cpp With gcc version: g++ (Debian 4.7.0-8) 4.7.0 (which says it's built from r187339 on the gcc 4.7 branch). On architecture: x86-64 Crashes with error message: test.cpp: In function ‘Foo* cause_ICE()’: test.cpp:7:6: internal compiler error: in verify_gimple_stmt, at tree-cfg.c:4258 Removing -std=c++0x makes it not crash. 4.6.3 does not crash. This looks similar to bug 49996, (but obviously different, because that one is still fixed).
[Bug c++/53364] New: [4.7/4.8 Regression] Wrong code generation
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53364 Bug #: 53364 Summary: [4.7/4.8 Regression] Wrong code generation Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: f...@fuhm.net On the following code, minimized from a much larger program: test.cpp = #include struct A { int m_x; explicit A(int x) : m_x(x) {} operator int() const { return m_x; } }; struct B : public A { public: explicit B(int x) : A(x) {} }; int data = 1; int main() { B b = B(10); b = std::min(b, B(data)); return int(b); } = Running: g++ -O2 -c test.cpp With gcc version: g++ (Debian 4.7.0-8) 4.7.0 (which says it's built from r187339 on the gcc 4.7 branch). On architecture: x86-64 The program ought to return 1, but instead, it returns randomness. Running valgrind confirms that this program is using uninitialized values. Testing with the debian gcc-snapshot package (trunk rev 187013) shows the same bug. Testing with the debian gcc 4.6.3 package does not show the bug. Using -O1 does not show the bug. Using -O1 -fstrict-aliasing shows the bug.
[Bug c++/53364] [4.7/4.8 Regression] Wrong code generation
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53364 --- Comment #1 from foom at fuhm dot net 2012-05-16 04:10:59 UTC --- Asm generated. Note that at no point is anything ever actually written to the stack, only read from it: : 0:83 3d 00 00 00 00 09 cmpl $0x9,0x0(%rip)# 7 7:48 8d 44 24 e8 lea-0x18(%rsp),%rax c:48 8d 54 24 d8 lea-0x28(%rsp),%rdx 11:48 0f 4f c2 cmovg %rdx,%rax 15:8b 00mov(%rax),%eax 17:c3 retq Making what ought to be a no-op change to the program, using class "A" instead of "B", thus: int main() { A a = A(10); a = std::min(a, A(data)); return int(a); } causes the following, correctly working, asm to be generated. This is the same output generated by adding "-fno-strict-aliasing" to the compile line for the original program. See that it now does write values onto the stack locations being read from. (It also seems rather crazy to me that gcc doesn't optimize such a simple program to use purely registers and no stack addresses, but I suppose that's a different bug.) : 0:8b 15 00 00 00 00mov0x0(%rip),%edx# 6 6:48 8d 44 24 e8 lea-0x18(%rsp),%rax b:48 8d 4c 24 d8 lea-0x28(%rsp),%rcx 10:c7 44 24 d8 0a 00 00 movl $0xa,-0x28(%rsp) 17:00 18:83 fa 09 cmp$0x9,%edx 1b:89 54 24 e8 mov%edx,-0x18(%rsp) 1f:48 0f 4f c1 cmovg %rcx,%rax 23:8b 00mov(%rax),%eax 25:c3 retq
[Bug c++/53364] [4.7/4.8 Regression] Wrong code generation
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53364 --- Comment #3 from foom at fuhm dot net 2012-05-16 04:28:21 UTC --- > Does -fno-tree-vrp fix the issue? Nope, "g++ -O2 -fno-tree-vrp -c test.cpp" is no different than without.
[Bug tree-optimization/61502] == comparison on "one-past" pointer gives wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #24 from James Y Knight --- FWIW, clang did consider this a bug and fixed it in https://bugs.llvm.org/show_bug.cgi?id=21327.
[Bug target/86005] [RISCV] Invalid intermixing of __atomic_* libcalls and inline atomic instruction sequences
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #4 from James Y Knight --- I think if RISCV wants to use out-of-line lock-free atomic helpers, it should give those another function name (for example, __sync_fetch_and_##OP##_##WIDTH), and provide them in libgcc.a, the same as the other architectures which use such out-of-line helpers. (But also, why doesn't it implement __atomic_add_fetch inline?) Since lock-free helper functions can be linked into a process as many times as you like without correctness issues, it's safe, and preferable, to provide them in the static runtime lib. That is quite unlike a potentially-locking __atomic_* function, which must share the same lock across the whole process, and thus must have only one implementation in a process, which is why they're provided separately by libatomic.so. It's not a good idea to conflate the two different things.
[Bug target/86005] [RISCV] Invalid intermixing of __atomic_* libcalls and inline atomic instruction sequences
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005 --- Comment #7 from James Y Knight --- (In reply to Jim Wilson from comment #6) > On Thu, 2018-05-31 at 15:07 +0000, foom at fuhm dot net wrote: > > (But also, why doesn't it implement __atomic_add_fetch inline?) > > If you don't have atomic instructions, then we call an out-of-line > function that uses locks. Except as mentioned in the initial message, it doesn't emit calls for atomic loads and stores too, but it needs to so that they also participate in the locking. > If you have atomic instructions, and it is a 32/64-bit operation, then > we inline it. > > If you have atomic instructions, and it is a 8/16-bit operation, then > we call a lock free out-of-line function that uses a sequence of > instructions to implement it using 32/64-bit atomic instructions. If you're building for rv32ia, yes, you certainly know that libatomic must implement __atomic_fetch_add_1 lock-free. So, sure, you shouldn't have a correctness issue by mixing the calls. Yet even so, if you actually needed to emit a call to a known-lock-free out-of-line function, it's better to give it a different name (e.g. __sync_*) and include that in libgcc.a. Emitting a call to the __atomic_* function means you require users to link against libatomic.so, which shouldn't be required here. > And > as mentioned previously, I have an unfinished prototype patch to fix > this by emitting the sequence of instructions inline. But doing that is fine, too, and likely preferable.
[Bug target/86005] [RISCV] Invalid intermixing of __atomic_* libcalls and inline atomic instruction sequences
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005 --- Comment #10 from James Y Knight --- I suppose since it doesn't affect most common platforms, nobody's noticed the brokenness yet? ARM is probably the most common architecture which is missing atomics on common CPU models, but when targeting common OSes (Linux, FreeBSD), you get to use the kernel atomic cmpxchg helpers, so the issue doesn't arise there. I haven't tested, but I don't think MIPS16 would be broken, since MIPS has native atomics, just not in the MIPS16 ISA. So, it calls out-of-line libgcc __sync_* routines, implemented in MIPS32 and which use LL/SC instructions. There's no problem mixing those with native load/store instructions. Anyways, for why mixing native load/store with __atomic_* functions is wrong, consider, int value = 4; Thread1: int oldval = __atomic_fetch_add(&value, 1, __ATOMIC_SEQ_CST); Thread2: __atomic_store_n(&value, 0, __ATOMIC_SEQ_CST); The only allowable results after executing both threads should be: oldval = 0, value = 1 -- if atomic_store executes first. oldval = 4, value = 0 -- if atomic_fetch_add executes first. But, if you implement __atomic_fetch_add with a lock, and implement __atomic_store with a native store instruction, you may get the "impossible" result, oldval = 4, value = 5 -- if atomic_store executes *during* atomic_fetch_add, between the load and store instructions. Oops.
[Bug libstdc++/89855] New: Inconsistent global namespace overload sets from #include
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855 Bug ID: 89855 Summary: Inconsistent global namespace overload sets from #include Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- In the following, I use the function "log" as an example, but this applies to effectively everything in cmath, and ::abs in cstdlib. The C standard library defines: double log(double); libstdc++ includes libc , and then does: namespace std { using ::log; float log(float); long double log(long double); double log(Any-Integral-Type); } libstdc++ does: #include using std::log; This has the unfortunate effect that code which includes and uses global ::log ends up accidentally calling the double overload of log. E.g., a program like this: #include float foo(float f) { return log(f); } Granted, the above code is non-portable, and may not even compile on some other standards-conforming implementation. I do not believe this is a standards-compliance issue in libstdc++ -- the header is permitted, but not required to define ::log. However, IMO, it's a *QoI* bug that libstdc++ doesn't provide consistent overload sets. The problem is that the behavior of the above code _very subtly_ changes upon adding or removing an #include which transitively has an "#include " in it. This can cause extremely surprising bugs. I'd suggest that either #include ought to define NO global ::log function at all (thus, the above program fails to compile), or it should define the entire overload set for ::log. No partial overload sets. Since not defining ::log from cmath is effectively impossible, given the current interfaces between libc and libstdc++, I think the latter is what should be done. Concretely, that simply means moving all of the global namespace "using std::log" (etc.) statements from libstdc++'s into libstdc++'s . (I would also suggest that it'd be reasonable for a future C++ standard to require that. E.g., it could say something like: While may or may not declare functions in ::std::, and may or may not declare functions in ::, if they _do_ declare any such name, they must define the complete set of required overloads, not a subset.)
[Bug c++/87521] [C++][ABI] Tail padding not reused for non POD struct with defaulted/deleted special member function as per Itanium ABI on x86-64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87521 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #5 from James Y Knight --- Since it's effectively arbitrary whether to allow tail padding or not, and the ABI doesn't actually say, it's not actually possible to say that gcc's behavior is "correct". The only way to actually resolve this is to fix the ABI to say what to do. It already has an open issue: https://github.com/itanium-cxx-abi/cxx-abi/issues/66 (The current thinking there is to require GCC's current implementation, AIUI.) Regarding comment #3: that doesn't prove anything -- it's entirely possible (not indicative of a bug) for a struct to be both trivially_copyable and not pod-for-layout. Your test-case is not valid, per [basic.types] para 3 -- which requires that the trivially_copyable type not be a base-class subobject in order for memcpy'ing the bytes to be valid. (The Itanium ABI also notes this.) And, for example, if you changed the code: -struct Base { +struct ReallyBase {}; +struct Base : public ReallyBase { then GCC also "fails that test" -- Base is now unambiguously not POD-for-layout since it has a base class, but it is still trivially_copyable.
[Bug c++/88115] New: Incorrect result from alignof in templates, if also using __alignof__.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115 Bug ID: 88115 Summary: Incorrect result from alignof in templates, if also using __alignof__. Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- On both GCC 8.2 and "trunk" on godbolt (https://godbolt.org/z/ykszUZ) given the following program, compiled for x86 -m32, the final GCCAlignOf static assert unexpectedly fails. However, if you comment out the three StdAlignOf lines, the assert starts passing. Or, if you swap the order such that GCCAlignOf comes first, then it will pass, and the StdAlignOf assert fails, instead. It looks like some caching inside GCC is still treating alignof and __alignof as the same thing, even though they now (since the fix for PR69560) are supposed to have differing behavior. Possibly this is due to both alignof and __alignof mangling to the same character? === static_assert(alignof(double) == 4, ""); static_assert(__alignof__(double) == 8, ""); template struct integral_constant { static constexpr _Tp value = __v; }; template using StdAlignOf = integral_constant; static_assert(StdAlignOf::value == 4, ""); template using GCCAlignOf = integral_constant; static_assert(GCCAlignOf::value == 8, ""); ===
[Bug libstdc++/88119] New: std::alignment_of returns wrong value (__alignof instead of alignof).
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88119 Bug ID: 88119 Summary: std::alignment_of returns wrong value (__alignof instead of alignof). Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- std::alignment_of is currently defined based on "__alignof__", but according to the standard [meta.unary.prop.query], it should return the same result as "alignof". And as of PR69560, __alignof and alignof now return different values in some circumstances. Test case for x86 with -m32, the static assert fails, but it should pass. #include static_assert(std::alignment_of::value == alignof(double), "");
[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 middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration
--- Comment #15 from foom at fuhm dot net 2010-02-10 23:24 --- Nope, adding -fno-indirect-inlining has no effect. I'm now using: g++-4.5 (Debian 4.5-20100202-1) 4.5.0 20100202 (experimental) [trunk revision 156452] Problem still occurs, -fno-ipa-cp still makes it go away. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290
[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration
--- Comment #17 from foom at fuhm dot net 2010-02-12 21:46 --- Thanks, I will try doing that. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290
[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration
--- Comment #18 from foom at fuhm dot net 2010-03-10 20:32 --- Sorry for the extreme delay in responding. I can confirm that applying that patch on top of: gcc-4.5 (Debian 4.5-20100227-1) 4.5.0 20100227 (experimental) [trunk revision 157109] *does* make my issue go away, and my program compile correctly without requiring the -fno-ipa-cp argument. Thank you. Should this report be reopened for that patch to be applied? I don't have the reopen option. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290
[Bug c++/65945] C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65945 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #9 from James Y Knight --- This also happens on Sparc. A test-case is really easy to make: int foo(bool&&, decltype(nullptr)&&, bool&&); void doit() { foo(false, nullptr, false); } save%sp, -104, %sp stb %g0, [%fp-6] /* WTF unaligned store */ st %g0, [%fp-5] stb %g0, [%fp-1] add %fp, -6, %g3 add %fp, -5, %g2 add %fp, -1, %g1 mov %g3, %o0 mov %g2, %o1 mov %g1, %o2 call_Z3fooObODnS_, 0 nop return %i7+8 nop .ident "GCC: (Debian 4.9.2-10) 4.9.2" This breaks building recent versions of clang on Sparc, because it calls emplace_back with nullptr, which results in an expression like the above.
[Bug target/46942] x86_64 parameter passing unnecessary sign/zero extends
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46942 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #10 from James Y Knight --- Well, the ABI doc doesn't appear to say anything about this still. GCC as of 5.1 seems to still do sign/zero extension of 8/16-bit arguments to 32-bit on the callee side. Clang does not. Both do extension of 32-bit arguments to 64-bit on the callee side. Both sign/zero-extend 8/16-bit values to 32-bits, and do /not/ truncate 64-bit values to 32-bit on the caller side. So it looks like GCC could still generate more optimal code by taking advantage of the "de-facto" ABI that lets you assume 32-bit sign/zero-extension has happened on arguments. But it'd also be real nice for this all to be actually documented, so there's something to point people to. :) BTW: This undocumentedness came up recently with an optimizer change in clang: libjpeg-turbo has some assembly code which was using the full 64-bit value of an argument register, assuming the upper bits would be zeroed, while on the C side, the function was declared as taking an "int". The upper bits are thus left undefined (as is correct, per the unwritten ABI rules), which broke the asm. https://github.com/libjpeg-turbo/libjpeg-turbo/pull/20 http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150907/138253.html
[Bug c++/65945] C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65945 --- Comment #11 from James Y Knight --- As far as I can tell, the C++ ABI discussion, http://comments.gmane.org/gmane.comp.lang.c++.abi/265 concluded that alignof(nullptr_t) should be alignof(void*) already. Any chance this change can be made and backported?
[Bug libstdc++/66438] New: libstdc++ 5.1 broke binary compat with old code using std::error_category
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438 Bug ID: 66438 Summary: libstdc++ 5.1 broke binary compat with old code using std::error_category Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- If you compile this program with GCC 4.9, but you have libstdc++ version 5.1 installed on your system. (E.g., this is the case for me because I'm using Debian unstable). #include int main() { std::error_code x = make_error_code(std::errc::no_such_file_or_directory); std::error_condition e = std::errc::no_such_file_or_directory; return x == e; } Then running it will return 0 instead of 1, like it should, (and did, with libstdc++ 4.9 installed). So, the thing to note, is that both "x" and "e" here have a category() of _ZSt16generic_categoryv() as their category instance -- NOT _ZNSt3_V216generic_categoryEv(), because it was built against the old headers. (This seems to be as intended.) Going through the calls, first we have this from libstdc++-v3/include/std/system_error: inline bool operator==(const error_code& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category().equivalent(__lhs.value(), __rhs) || __rhs.category().equivalent(__lhs, __rhs.value())); } which calls, from libstdc++-v3/src/c++11/compatibility-c++0x.cc: bool error_category::equivalent(int __i, const error_condition& __cond) const noexcept { return default_error_condition(__i) == __cond; } which calls, from the same file: error_condition error_category::default_error_condition(int __i) const noexcept { if (*this == system_category()) return error_condition(__i, _V2::system_category()); return error_condition(__i, _V2::generic_category()); } which returns a _V2::generic_category() object. Oops. Now we're in big trouble! Then, back to error_category::equivalent, where it calls, from libstdc++-v3/include/std/system_error: inline bool operator==(const error_condition& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category() == __rhs.category() && __lhs.value() == __rhs.value()); } Which fails, because __lhs.category() is the V2 generic_category, and __rhs.category() is the "V1" generic_category.
[Bug libstdc++/66438] libstdc++ 5.1 broke binary compat with old code using std::error_category
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438 James Y Knight changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #5 from James Y Knight --- Sorry, please try again. Andreas Schwab: I did compile it with the libstdc++ that came with the compiler -- and then I upgraded the binary libstdc++.so to the newer one that came with gcc 5. And it broken. Thus the report of breaking binary compat. (It also happens with new compiles in Debian because of what Gianfranco says) Andrew Pinski: The *one and only purpose* of the file libstdc++-v3/src/c++11/compatibility-c++0x.cc is to provide binary compatibility for c++11 binaries compiled against older libstdc++ versions, and now running against a newer one. If libstdc++.so.6, version 5.1, is not supposed to work properly with c++ binaries compiled by the 4.9 compiler, it should not be providing these compatibility symbols at all. Since it does provide them, there is clearly intent to provide compatibility so, it ought to work. Or they should be deleted...
[Bug libstdc++/66438] libstdc++ 5.1 broke binary compat with old code using std::error_category
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438 --- Comment #9 from James Y Knight --- What good is having special code to allow linking compatibility, if the program then can't work anyways? Isn't that anti-useful? > I didn't realise you were the maintainer and knew what's supposed to work. No, of course...I'm only a user > If you can provide a patch I'm not certain, but it seems like probably the old-ABI error_category::default_error_condition(int) ought to just return an error_condition also with the old ABI, instead of the new one? CC'ing debian's gcc maintainer, because the stated lack of desire for compatibility between libstdc++ version 5, and g++ 4.9 seems like it's probably something he wasn't aware of when upgrading.
[Bug libstdc++/66438] libstdc++ 5.1 broke binary compat with old code using std::error_category
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438 James Y Knight changed: What|Removed |Added CC||doko at gcc dot gnu.org --- Comment #10 from James Y Knight --- Oops, actually cc'ing doko this time (hopefully.)
[Bug c++/65945] C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65945 --- Comment #12 from James Y Knight --- Since this would at least theoretically be a c++11 ABI change -- although it seems likely not to impact the ABI of most actual software -- it seems like it'd be a really good idea to fix it ASAP, before too many people start depending on GCC 5.1's C++11 ABI.
[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration
--- Comment #13 from foom at fuhm dot net 2010-01-12 06:27 --- The crash is still present for my code. I'm using: g++ (Debian 20091228-2) 4.5.0 20091228 (experimental) [trunk revision 155486] on AMD64. Passing -fno-ipa-cp also makes the bug disappear for me. But apparently r154673 did not fix the underlying issue, only make it unreproducible with the test case here. I can try again to minimize, but I'm not optimistic: this bug seems to appear and disappear almost randomly with minor adjustments to the code, and unfortunately I cannot post my complete code. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290
[Bug c++/42797] New: call of overloaded 'allocator()' is ambiguous
On Linux x86_64 g++ --version: g++ (Debian 20100117-1) 4.5.0 20100117 (experimental) [trunk revision 155979] Compiling with: g++ -O2 -g -std=c++0x -c test.cpp The following program: #include #include struct Foo { Foo() {} template Foo(Tp *p) {} }; void foo() { std::map > the_map; the_map[1] = std::vector(); } Produces the below error. However, it *doesn't* produce an error if compiled without the -g switch (nor with -O1 instead of -O2). In file included from /usr/include/c++/4.5.0/bits/move.h:38:0, from /usr/include/c++/4.5.0/bits/stl_pair.h:60, from /usr/include/c++/4.5.0/bits/stl_algobase.h:66, from /usr/include/c++/4.5.0/vector:61, from test.cpp:1: /usr/include/c++/4.5.0/type_traits: In constructor 'std::vector<_Tp, _Alloc>::vector(std::vector::size_type, const value_type&, const allocator_type&) [with _Tp = Foo, _Alloc = std::allocator, std::vector::size_type = long unsigned int, value_type = Foo, allocator_type = std::allocator]': /usr/include/c++/4.5.0/type_traits:224:67: instantiated from 'const bool std::__is_constructible_helper, const int&&>::__value' /usr/include/c++/4.5.0/type_traits:235:5: instantiated from 'std::is_constructible, const int&&>' /usr/include/c++/4.5.0/bits/stl_map.h:451:11: instantiated from here /usr/include/c++/4.5.0/type_traits:224:67: error: call of overloaded 'allocator()' is ambiguous /usr/include/c++/4.5.0/bits/allocator.h:103:7: note: candidates are: std::allocator<_Tp>::allocator(const std::allocator<_Tp>&) [with _Tp = Foo, std::allocator<_Tp> = std::allocator] /usr/include/c++/4.5.0/bits/allocator.h:101:7: note: std::allocator<_Tp>::allocator() [with _Tp = Foo] /usr/include/c++/4.5.0/type_traits:224:67: error: call of overloaded 'allocator()' is ambiguous /usr/include/c++/4.5.0/bits/allocator.h:103:7: note: candidates are: std::allocator<_Tp>::allocator(const std::allocator<_Tp>&) [with _Tp = Foo, std::allocator<_Tp> = std::allocator] /usr/include/c++/4.5.0/bits/allocator.h:101:7: note: std::allocator<_Tp>::allocator() [with _Tp = Foo] /usr/include/c++/4.5.0/type_traits:218:2: error: call of overloaded 'allocator()' is ambiguous /usr/include/c++/4.5.0/bits/allocator.h:103:7: note: candidates are: std::allocator<_Tp>::allocator(const std::allocator<_Tp>&) [with _Tp = Foo, std::allocator<_Tp> = std::allocator] /usr/include/c++/4.5.0/bits/allocator.h:101:7: note: std::allocator<_Tp>::allocator() [with _Tp = Foo] -- Summary: call of overloaded 'allocator()' is ambiguous Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: foom at fuhm dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42797
[Bug c++/42797] call of overloaded 'allocator()' is ambiguous
--- Comment #1 from foom at fuhm dot net 2010-01-19 06:15 --- Error also occurs with: g++ -O1 -fipa-sra -g -std=c++0x -c test.cpp -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42797
[Bug libstdc++/45060] New: Wreorder warning in bits/hashtable.h
When compiling with -Wsystem-headers, I noticed: /usr/include/c++/4.5/bits/hashtable.h:179:30: warning: 'std::_Hashtable, std::_Identity, ..., ..., std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, true, true>::_M_rehash_policy' will be initialized after [-Wreorder] /usr/include/c++/4.5/bits/hashtable.h:176:30: warning: 'std::_Hashtable, std::_Identity, ..., ..., std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, true, true>::_Node** std::_Hashtable, std::_Identity, ..., ..., std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, true, true>::_M_buckets' [-Wreorder] /usr/include/c++/4.5/bits/hashtable.h:646:5: warning: when initialized here [-Wreorder] Moving the initialization of _M_buckets to before _M_bucket_count should fix it. This is actually the *only* extra warning I got when compiling a large C++ codebase with -Wsystem-headers, which is great! -- Summary: Wreorder warning in bits/hashtable.h Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: foom at fuhm dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45060
[Bug c++/44487] New: pair of references doesn't work in c++0x mode
This program doesn't compile with g++-4.5 -std=c++0x -c test.cpp I'm using: g++-4.5 (Debian 4.5.0-5) 4.5.1 20100602 (prerelease) I also verified the same behavior on: g++ (Debian 20100530-1) 4.6.0 20100530 (experimental) [trunk revision 160047] #include int x, y; std::pair foo() { std::pair blah(x, y); return blah; } It says: In file included from /usr/include/c++/4.5/utility:71:0, from /tmp/test.cpp:1: /usr/include/c++/4.5/bits/stl_pair.h: In constructor std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int&, _T2 = int&, std::pair<_T1, _T2> = std::pair]: /tmp/test.cpp:8:12: instantiated from here /usr/include/c++/4.5/bits/stl_pair.h:113:30: error: invalid initialization of non-const reference of type int& from an rvalue of type std::remove_reference::type /usr/include/c++/4.5/bits/stl_pair.h:113:30: error: invalid initialization of non-const reference of type int& from an rvalue of type std::remove_reference::type It works without -std=c++0x, and it seems like that ought to work in c++0x too. Furthermore, this slightly modified program, making "blah" const (which I think shouldn't make a difference, as it's the outermost qualifier of a local variable) causes it to successfully compile: #include int x, y; std::pair foo() { const std::pair blah(x, y); return blah; } -- Summary: pair of references doesn't work in c++0x mode Product: gcc Version: 4.5.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: foom at fuhm dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44487
[Bug libstdc++/97449] New: libstdc++ cannot be compiled with clang after 3427e31331677ca826c5588c87924214f7e5c54b
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97449 Bug ID: 97449 Summary: libstdc++ cannot be compiled with clang after 3427e31331677ca826c5588c87924214f7e5c54b Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- After 3427e31331677ca826c5588c87924214f7e5c54b, "clang -std=c++17" (using libstdc++ headers), on a file that has simply "#include " fails with this error: In file included from :1: /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/variant:1032:10: error: no matching constructor for initialization of 'std::__nonesuch' return __nonesuch{}; ^ ~~ /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/type_traits:2953:5: note: candidate constructor not viable: requires 1 argument, but 0 were provided __nonesuch(__nonesuch const&) = delete; ^ (https://godbolt.org/z/951jYr) I believe Clang is correct to reject this code, due to http://eel.is/c++draft/temp.res#general-8.1 """ The program is ill-formed, no diagnostic required, if: - no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated """ The invalid return statement probably needs to be made dependent on __visit_ret_type_mismatch just like the static_assert.
[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115 --- Comment #6 from James Y Knight --- > c++: Change the mangling of __alignof__ [PR88115] The new mangling chosen for __alignof__(type) seems problematic, and I think this commit ought to be reverted until a new mangling scheme has been chosen. At the very least, both __alignof__(expression) and __alignof__(type) can't both be encoded as "v111__alignof__", with no indication of whether the argument is a type or an expression, because that's ambiguous. Possibly it'd be okay to use v112__alignof__z and v112__alignof__t, similar to how "az" and "at" are used for standard alignof expression/type. That solves the ambiguity. But -- this violates the generic grammar, which doesn't allow for a vendor operator to take type arguments at all. ::= v ::= Now...possibly it's okay to violate that and pass a type, regardless. But, then the demangler needs to know what every vendor extension operator's semantics are in order to demangle -- which seems against the intent of the standardized "vendor operator" syntax. So, that's not great. This seems like a problem which may be worth solving properly and generally in the itanium ABI -- maybe now's the time to actually do this? (Fixing this would allow __typeof__, __builtin_convertvector, and __builtin_offsetof to be mangleable too...) See also PR13740 and PR11078, for earlier (MUCH earlier!) discussion of possible mangling syntax extensions for this sort of thing. Unfortunately, it never went anywhere... ISTM that the most promising proposal in those earlier threads was to add a "Y" to both type and expression expansions. To support vendor-specific builtins which returns a type, and can take types or expressions as arguments (e.g. typeof), add: ::= Y + E To support vendor-specific builtins which return a value, and can take types or expressions as arguments (e.g. __builtin_offsetof, or __alignof__): ::= Y + E
[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115 --- Comment #7 from James Y Knight --- I've created an ABI proposal against itanium abi, here: https://github.com/itanium-cxx-abi/cxx-abi/issues/112 I realized since writing my last comment here that ::= u [] # vendor extended type has been added a few months ago. Therefore, nothing needs to be added to support extended expressions as . And, therefore, since 'u' is also free in expression, I've proposed to simply add the same 'u' syntax to "expression", rather than using "Y", as per previous comment. That is: ::= u [] # vendor extended expression
[Bug target/98495] New: X86 _mm_extract_pi16 incorrectly sign extends result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98495 Bug ID: 98495 Summary: X86 _mm_extract_pi16 incorrectly sign extends result Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- #include int test(__m64 a) { return _mm_extract_pi16 (a, 0); } Compiles to (x86_64 gcc, -O2): pextrw $0, %xmm0, %eax cwtl ret Which results in the value being sign-extended from 16-bits to 32-bits. The intel docs for PEXTRW state that the upper bits are zeroed, and state that _mm_extract_pi16 is supposed to implement PEXTRW. So, the expected result is no sign extension: pextrw $0, %xmm0, %eax ret I'd note that this is not a regression due to the new MMX with SSE2 changes -- GCC has had this bug as far back as I can see. It is currently present on trunk both for the MMX and SSE2 implementations. Both clang and MSVC zero-extend rather than sign-extend. And, for that matter, GCC's _mm_extract_epi16 function _also_ zero-extends -- it was fixed in PR45336 for GCC 4.6.
[Bug target/98522] New: _mm_cvttps_pi32 and _mm_cvtps_pi32 raise spurious FP exceptions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98522 Bug ID: 98522 Summary: _mm_cvttps_pi32 and _mm_cvtps_pi32 raise spurious FP exceptions Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- This is a regression due to the MMX in SSE work in GCC10. As far as I can tell, it affects only these two functions. Example test, which should return 0, but instead throws SIGFPE: #pragma stdc fenv_access #define _GNU_SOURCE #include #include __attribute__((noinline)) __m64 test(__m128 a) { return _mm_cvtt_ps2pi(a); } int main() { feenableexcept(FE_INVALID); __m128 x = (__m128)(__m128i){0xLL, 0x7fffLL}; volatile __m64 y = test(x); } In GCC 10 and trunk, the function test is compiled to: cvttps2dq xmm0, xmm0 ret which will convert the upper 64 bits as well as the lower 64 bits -- and therefore raises FP exceptions accordingly. But, it ought to be ignoring the upper 64bits.
[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115 --- Comment #9 from James Y Knight --- Proposed patch posted for the itanium-cxx-abi: https://github.com/itanium-cxx-abi/cxx-abi/pull/115/files using the syntax: u * E And to Clang, to use that syntax: https://reviews.llvm.org/D93922 I hope both GCC and Clang can do the same thing here.
[Bug c++/98804] New: GCC misparses template in pack expansion as comparison
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98804 Bug ID: 98804 Summary: GCC misparses template in pack expansion as comparison Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net CC: richard-gccbugzilla at metafoo dot co.uk Target Milestone: --- GCC parses the following program (by Richard Smith) as `g` less-than `a` greater-than `(a)` instead of a call to the function `g` with template-args `a`, and argument-list `(a)`. And thus, it fails to compile. (Compile with -std=c++20) struct X { constexpr X(int&) {} }; template void g(F); template void g(int); void g(...); template auto h(A ...a)->decltype (g (0, g < a > (a) ...)) { } void test () { h(0); } - I originally noticed this bug with the following test from Clang's test-suite, while working on a mangling bug in Clang. In this original test-case, GCC does successfully compile, but the mangling is weird, exposing that the same misparse occurred. namespace pr30440 { template void g(F); template auto h(A ...a)->decltype (g (0, g < a > (a) ...)) { } void pr30440_test () { h(); } } GCC mangles as: _ZN7pr304401hIJEEEDTcl1gLi0Espgtlt1gfp_fp_EEDpT_ with greater/less operators in the mangling. But it should've been: _ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIXfp_EEfp_EEEDpT_ ^^^ with a template-arg.
[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115 --- Comment #10 from James Y Knight --- Seeing as GCC is now in Stage 4 before the next release, I'd like to ping this bug. Should the priority be upgraded? I think fixing this so that GCC doesn't use 'v111__alignof__' should be considered a release-blocker: either the mangling change should be reverted to the previous behavior, or fixed. FWIW, the change to clang has been committed, and is planned to be in the upcoming Clang 12 release (https://reviews.llvm.org/rG9c7aeaebb3ac1b94200b59b111742cb6b8f090c2)
[Bug inline-asm/100953] Add memory clobbers just for reads or just for writes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100953 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #3 from James Y Knight --- For the compiler-barrier use-cases, you can use the __atomic_signal_fence builtin instead of an empty inline-asm statement. E.g. if you want to make sure that all writes apperaing after a barrier are actually emitted after all reads/writes appearing before the barrier, use __atomic_signal_fence(__ATOMIC_RELEASE).
[Bug libstdc++/104602] New: std::source_location::current uses cast from void*
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104602 Bug ID: 104602 Summary: std::source_location::current uses cast from void* Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- I'm working on implementing __builtin_source_location() in Clang (https://reviews.llvm.org/D120159). In testing it against the libstdc++ header, I ran into a minor issue. "current()" in GNU libstdc++ is defined as so: static consteval source_location current(const void* __p = __builtin_source_location()) noexcept { source_location __ret; __ret._M_impl = static_cast (__p); return __ret; } But! A static_cast from a `const void*` parameter to `const __impl*` is not permitted in constexpr evaluation: """ 5. An expression E is a core constant expression unless the evaluation of E, [...] would evaluate one of the following: [...] 5.15. a conversion from type cv void* to a pointer-to-object type;" """ http://eel.is/c++draft/expr.const#5.15 Clang diagnoses this rule, but GCC apparently does not. (it's not really clear to me why this rule really needs to exist in the standard -- why bother to police which kinds of pointer casts you're allowed to do, instead of just raising an error upon _access_ through the wrong type?) Anyhow, to workaround this issue, I plan to simply hardcode an exception to the check in Clang for casts which occur in a "std::source_location::current" method. Yet, although it's perhaps too late to avoid this workaround, it'd be nice if libstdc++ didn't require the use of an invalid cast. In clang (in my proposed change), __builtin_source_location already returns the expected `const __impl*` type, rather than `const void*` as it does in GCC. So, the issue is only the cast TO `void*` and back again in libstdc++. ISTM this would be fixed by moving the `static_cast ` into the default parameter expression. That would then be a no-op cast on clang, and an (invalid but undiagnosed) cast from void in GCC.
[Bug libstdc++/104602] std::source_location::current uses cast from void*
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104602 --- Comment #4 from James Y Knight --- Yea that should work. Or even just `auto`.
[Bug target/55522] -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55522 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #12 from James Y Knight --- https://github.com/llvm/llvm-project/issues/57589 was just filed, requesting to fix this behavior in Clang, as well. Since Clang is effectively only doing it in the first place to match GCC's behavior, my feeling is that it'd be better not to make such a change in Clang only. However, I'd just like to give my support to changing this in GCC (either to stop automatically linking against crtfastmath.o altogether, or to at least stop doing so with -shared). And, if there is a change here, would certainly then propose to match the new behavior in Clang.
[Bug inline-asm/98096] Inconsistent operand numbering for asm goto with in-out operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98096 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #7 from James Y Knight --- Previously, you never needed to care about the numbering of the extra hidden input constraints generated for an in-out constraints, because they were _last_. Their existence previously only mattered in that you needed to count them as part of the "max 30" constraint limit. That's why it is sensible to _keep_ these internal constraints last -- after ALL user-specified constraints, including asm-goto labels. Putting in the middle, and forcing users to count them just adds extra unnecessary complexity to the user-facing API. It appears to me that the GCC decision here was accidental, and that when pointed out, the bug was simply documented rather than fixed. That's unfortunate.
[Bug c++/56958] Spurious set but not used variable warning in empty pack expansion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #6 from James Y Knight --- I agree with the other people noting that it isn't _useful_ to warn about this construct, and that this ought to be considered a valid bug, not working as intended.
[Bug tree-optimization/100038] -Warray-bound triggers false positives
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #8 from James Y Knight --- Here's a shorter test-case, reproduces with g++-11 -O2 -Warray-bounds: ``` struct SparseBitVectorElement { long Bits[2]; int find_first() const; }; int SparseBitVectorElement::find_first() const { for (unsigned i = 0; i < 2; ++i) if (Bits[i]) return i; // __builtin_unreachable(); // Illegal empty element } ``` The "__builtin_unreachable" at the end of the function seems to be the trigger for the issue -- presumably because the compiler decides to omit the loop end condition as being unnecessary. Trying the above on godbolt, it appears that it no longer occurs on gcc trunk for this test-case. But, I don't know if that was intentionally fixed or just happens not to trigger here. (I haven't tried compiling LLVM with a gcc trunk snapshot to see if all similar warnings have gone away.)
[Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #5 from James Y Knight --- The originally-reported program still appears to exhibit the issue. Just looking at the unwind code -- and without attempting to test anything -- it appears that the solution may be as simple as inserting two lines: if (found_type == found_terminate) return _URC_FATAL_PHASE1_ERROR; at line 651 of eh_personality.cc (https://github.com/gcc-mirror/gcc/blob/b85a03ae11b157d60ddf93b71632efe0bde3bafd/libstdc%2B%2B-v3/libsupc%2B%2B/eh_personality.cc#L651) I believe that would abort the search phase (similarly to what happens if you run out of unwind frames before finding any catch handler) and cause _Unwind_RaiseException to return _URC_FATAL_PHASE1_ERROR, which then causes _cxa_throw to call terminate().
[Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918 --- Comment #6 from James Y Knight --- I realize that my suggestion above could only solve _most_ of the problem -- e.g. the original example, where the noexcept function doesn't have a try/catch in it. In that original example, there's no entry for the IP of the call in the LSDA table. The personality fn already knows during phase1 that this indicates termination -- but it simply fails to actually trigger the terminate in phase1, even though it easily could (& should!). However, in the example from comment #4, there _WILL_ be an entry in the callsite table covering the throw (necessarily, in order to to catch type "float"), so the "missing callsite => terminate" mechanism isn't applicable in that case. As the comment mentioned, to handle that, we'd need some alternative indication for termination which can be put in the action list. ISTM this could be done most straightforwardly by using an action record with a ttype pointing to a new ABI-defined special-purpose symbol (e.g. "__cxxabiv1::__eh_noexcept"). In libsupc++'s impl, that symbol can be an object whose type is a new std::type_info subclass, whose __do_catch overload calls terminate. Thus, when the personality fn falls through all the _actual_ catch action records, and comes to this, last one, it will query whether it can catch an exception by calling its __do_catch, and immediately trigger termination. GCC, then, can emit that as the last "catch" action in the chain for a try/catch in a noexcept function (instead of the cleanup action with code that calls std::terminate explicitly in the cleanup, that it does now).
[Bug target/98112] Add -f[no-]direct-access-external-data & drop HAVE_LD_PIE_COPYRELOC
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98112 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #8 from James Y Knight --- The requested semantics were subsequently implemented by GCC as `-mno-direct-extern-access` in PR100593, is that right? (Except that it was done only for x86-64, rather than being arch-independent.) So maybe this PR should be closed?
[Bug c++/36685] clarify/diagnose use of weak constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36685 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #4 from James Y Knight --- The interaction of __attribute__((weak)) and const int was recently explored in Clang in this thread: https://discourse.llvm.org/t/weak-attribute-semantics-on-const-variables/62311 Strangely, it appears that Clang and GCC have opposite odd behavior currently: GCC appears to evaluate weak constants _only_ in constant evaluation (so long as
[Bug c++/36685] clarify/diagnose use of weak constant
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36685 --- Comment #5 from James Y Knight --- (oops submitted commit by mistake, continuing...) Strangely, it appears that Clang and GCC both have odd behaviors currently, but somewhat opposites: - GCC appears to evaluate weak constants _only_ in frontend constant evaluation. It does not treat them as known during backend optimizations. (However, GCC does not allow you to use such a variable in a context that is required to be constant by language rules). - Clang evaluates weak constants _only_ in backend optimizations, and never in frontend constant evaluation. Clang will be changing to stop optimizing based on weak constant value, so that they are consistently treated as unknown values. I'd suggest that GCC probably ought to do the same (by no longer constant evaluating such variables).
[Bug c++/99858] Wrong throw-expression behaviour with reference to pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99858 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #3 from James Y Knight --- This is a mess. Clang gets it "right" only through a really awful hack, which breaks std::rethrow_exception, and which I'm now proposing to remove. See https://github.com/llvm/llvm-project/issues/55340#issuecomment-1152755112 I don't believe there's a way to actually get this correct in the Itanium ABI as it stands.
[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #31 from James Y Knight --- It doesn't make sense to have a mode in which `int array[0]` is accepted but is not a flex array. Either that should be a compilation error (as the standard specifies), or it should be a flex array. Accepting it as an extension but having it do the wrong thing is not useful or helpful. Note that Clang has a dedicated warning flag for zero-length arrays: -Wzero-length-array, so anyone who wants to prohibit them may use -Werror=zero-length-array. It would be helpful for GCC could follow suit there. The other proposed modes: - Treat all trailing arrays as flexible arrays. the default behavior; - Only treating [], [0], and [1] as flexible array; - Only treating [] and [0] as flexible array; do make sense.
[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 --- Comment #33 from James Y Knight --- (In reply to qinzhao from comment #32) > there is a Bugzilla that has been filed for GCC to request the same warning > for GCC: > https://gcc.gnu.org/bugzilla//show_bug.cgi?id=94428 > > -Wzero-length-array Great. Adding that flag, and eliminating the -fstrict-flex-arrays=3 option from this proposal would be good. > As suggested by Siddhesh in comment#23, -Wstrict-flex-arrays might be > necessary to be added too, and > -Wzero-length-array will be an alias to > -Wstrict-flex-arrays=3 I don't understand what the -Wstrict-flex-arrays warning and its multiple levels is proposed to actually do. Is it supposed to warn on the structs that change behavior in the corresponding -fstrict-flex-array=LEVEL? But that would mean -Wstrict-flex-arrays=1 would warn on any array at the end of a struct which has a size other than 0 or 1. That's clearly not going to be actually practical...so perhaps you had something else in mind?
[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 --- Comment #36 from James Y Knight --- (In reply to Kees Cook from comment #34) > > Great. Adding that flag, and eliminating the -fstrict-flex-arrays=3 option > > from this proposal would be good. > > Hmm? No, -fstrict-flex-arrays=3 is still needed (because it changes compiler > _behavior_, e.g. for proper FORTIFY coverage or trailing arrays, etc). There is no purpose served by writing a struct member `int x[0];` other than to create a FAM. Zero-length arrays are not permitted by the C standard, but are a GCC compiler extension explicitly for the purpose of creating a FAM. This is entirely unlike `int x[1];` or `int x[10];` which of course have a primary meaning as a concrete array size... If the linux kernel doesn't want to allow `int x[0];` FAMs, then prohibit them entirely using -Werror=zero-length-array (once it's implemented).
[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 --- Comment #37 from James Y Knight --- (In reply to qinzhao from comment #35) > I think that -Wstrict-flex-arrays will need to be cooperated with > -fstrict-flex-arrays=N, i.e, only when -fstrict-flex-arrays=N is presenting, > -Wstrict-flex-arrays will be valid and report the warnings when see a [0], > or [1], or any trailing array based on N: When -fstrict-flex-arrays is used, I'd expect the existing -Warray-bounds warning to already emit diagnostics in the cases you list, because those cases should no longer be special-cased to act as a FAM, and thus no longer explicitly suppress it.
[Bug libstdc++/111351] New: constexpr std::string objects permitted to escape constant evaluation when SSO
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351 Bug ID: 111351 Summary: constexpr std::string objects permitted to escape constant evaluation when SSO Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- In C++20, libstdc++ currently allows an std::string instance to escape from constant evaluation to runtime, as long as the string fit within the SSO length. E.g., as a global variable, compiled with -std=c++20: constexpr std::string s1; // OK constexpr std::string s1 = ""; // OK constexpr std::string s1 = "0123456789abcde"; // OK constexpr std::string s2 = "0123456789abcdef"; // FAIL I believe all of the above ought to fail to compile. This will result in user code which can be built or not based on whether their string happens to fit within the SSO string length. I find that quite unfortunate, since it is supposed to be an internal implementation detail/optimization, and this makes it effectively part of the API that code will grow to depend on. As comparison, libc++ rejects all the above examples, by forcing the SSO-size to zero in constant evaluation context, so that a pointer to an external allocation is always used. This was brought to my attention from https://quuxplusone.github.io/blog/2023/09/08/constexpr-string-firewall/
[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351 --- Comment #4 from James Y Knight --- vector and string are different in one key way: a zero-sized vector has no accessible storage, while a zero-sized string has 1 byte of readable storage -- the NUL terminator. Because of that, I don't think it's unreasonable for a zero-length vector to be constinit'able, while a zero-length string is not. But, certainly the _more_ concerning issue is with non-zero-sized strings where the validity of the program depends on what exact SSO size was chosen by the implementation. > libc++'s choice is confusing even for the experts, who have to maintain its > split-brain SSO logic forever because Hyrum's Law "Hyrum's Law" is exactly why I think it's a mistake to permit SSO-allocated strings. It makes the SSO length a critical part of the interface. People will start writing code which assumes that a constexpr global string of size "N" works, and that will cause problems for other standard libraries which use a different SSO size "M", if M < N. E.g. if libc++ starts allowing this, then people who first target libc++ will find that strings up to 22 characters work, and be surprised/annoyed by libstdc++ failing to build their program. It is much simpler to say to users "you cannot make a constexpr std::string unless it lives fully within constant-evaluation-time." then to also add "...OR unless the size is short enough, where that size depends on your implementation."
[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351 --- Comment #5 from James Y Knight --- > Does using __builtin_is_constant_p on the union member not work? I've created a proof-of-concept patch for libc++ to support SSO strings during constant evaluation. It works. If everyone disagrees with me and believes that this is a really awesome foot-gun to give to users, I will go ahead and propose that patch to libc++ maintainers. (As mentioned, that'll cause more code to be compilable under libc++ than is possible to permit under libstdc++/MSVC implementations). However, I continue to believe the opposite outcome, prohibiting this everywhere, would be preferable.
[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351 --- Comment #7 from James Y Knight --- On the libc++ side, a suggestion was given that instead of making this an _error_, we could instead emit a warning if "a constexpr or constinit object is a basic_string or contains a basic_string subobject, or the definition of a constexpr or constinit variable extends the lifetime of a temporary object that meets the previous condition." I think that was a really great suggestion -- diagnosing via a warning is a nicer solution than putting is_constant_evaluated hacks into the library (as MSVC had, and libc++ currently has but will likely remove). One could either hardcode std::basic_string for the diagnostic, or add a new type-attribute to permit any type to opt-in to such a warning. You'd want to use it if you have a type where you don't _intend_ to support constant-initialization, but where it may sometimes be possible as an implementation detail, and you want to tell users not to rely on that implementation detail.
[Bug c++/118883] New: [C++17] Incorrectly requires initializer for static constexpr class-member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118883 Bug ID: 118883 Summary: [C++17] Incorrectly requires initializer for static constexpr class-member Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: foom at fuhm dot net Target Milestone: --- The following ought to be accepted in C++17 and later: ``` struct Foo {int* x = 0;}; class Bar { static constexpr Foo foo; }; ``` But GCC it rejects with `error: 'constexpr' static data member 'foo' must have an initializer`. The requirement was removed by P0386r2, which modified class.data.static from "shall specify a brace-or-equal-initializer" to "may specify a brace-or-equal-initializer".
[Bug c/119526] standard attributes should be preserved in redeclarations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119526 James Y Knight changed: What|Removed |Added CC||foom at fuhm dot net --- Comment #2 from James Y Knight --- Presumably also in this example, "i" should remain deprecated: struct S { char c; [[deprecated]] int i; }; struct S { char c; int i; };