[Bug c++/114675] New: warning for "reference to not fully constructed object"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114675 Bug ID: 114675 Summary: warning for "reference to not fully constructed object" Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- We have an object that contains several sub-objects that should reference each other through interface pointers. I'd like to make sure that interface pointers given to objects constructed later already point to initialized objects. So, for struct everything { everything() : a(), b(c), c(a) { } A a; B b; C c; }; I'm passing a reference to the not-yet-constructed C object to B's constructor, so this is unsafe despite being legal C++. I wonder if it would be possible to generate a warning here.
[Bug target/113981] New: risc-v: non-void C++ function with no return statement has no ret
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113981 Bug ID: 113981 Summary: risc-v: non-void C++ function with no return statement has no ret Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- On RISC-V with -O3, the C++ program int f() {} emits a completely empty function. It correctly warns about the missing return statement, but also does not emit a "ret" instruction.
[Bug target/113980] New: risc-v: unnecessary sign-extend after lw, and more
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113980 Bug ID: 113980 Summary: risc-v: unnecessary sign-extend after lw, and more Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- On RISC-V with -O3, #include extern uint32_t volatile d; extern uint8_t volatile o; void f() { uint32_t t; while((t = d) & 0x8000) ; o = t; } generates f: lui a3,%hi(d) .L2: lw a5,%lo(d)(a3) sext.w a4,a5 blt a5,zero,.L2 andia4,a4,0xff lui a5,%hi(o) sb a4,%lo(o)(a5) ret The result of the lw instruction is already sign-extended, so the sext.w instruction is unnecessary in any case. It is extra unnecessary when the value is subsequently truncated with an and instruction, which itself is unnecessary for a sb instruction. To keep this bug report focused, I'd limit the problem description to the sign-extend -- if the others warrant opening extra bug reports, I can do that as well.
[Bug target/111704] New: ICE in extract_insn, at recog.cc:2791 on aarch64-linux-gnu during RTL pass: cprop_hardreg
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111704 Bug ID: 111704 Summary: ICE in extract_insn, at recog.cc:2791 on aarch64-linux-gnu during RTL pass: cprop_hardreg Product: gcc Version: 12.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- While [building GHDL 3.0.0]() on Debian, using gcc 12 as a base, we get an ICE: aarch64-linux-gnu-gcc-12 -c -I./ -I../../src -I../../src/vhdl -I../../src/synth -I../../src/grt -I../../src/psl -I../../src/vhdl/translate -I../../src/ghdldrv -I../../src/ortho -I../../src/ortho/llvm6 -I../../src/synth -I../../src/ghdldrv -gnat12 -gnaty3befhkmr -g -gnatwa -gnatwC -gnatf -g -O2 -ffile-prefix-map=/<>=. -fstack-protector-strong -fstack-clash-protection -mbranch-protection=standard -gno-record-gcc-switches -gnata -I- /<>/src/synth/synth-disp_vhdl.adb /<>/src/ghdldrv/ghdldrv.adb: In function ‘Ghdldrv.Gen_Makefile’: /<>/src/ghdldrv/ghdldrv.adb:2022:8: error: unrecognizable insn: (insn 1387 147 204 13 (parallel [ (set (mem/c:SI (plus:DI (reg/f:DI 29 x29) (const_int -260 [0xfefc])) [36 files_it+4 S4 A32]) (reg:SI 2 x2 [244])) (set (mem/c:SI (plus:DI (reg/f:DI 29 x29) (const_int -256 [0xff00])) [36 files_it+8 S4 A64]) (reg:SI 1 x1 [604])) ]) "/<>/src/ghdldrv/ghdldrv.adb":1926:19 -1 (expr_list:REG_DEAD (reg:SI 2 x2 [244]) (expr_list:REG_DEAD (reg:SI 1 x1 [604]) (nil during RTL pass: cprop_hardreg +===GNAT BUG DETECTED==+ | 12.3.0 (aarch64-linux-gnu) in extract_insn, at recog.cc:2791 | | Error detected around /<>/src/ghdldrv/ghdldrv.adb:2022:8| | Compiling /<>/src/ghdldrv/ghdldrv.adb| | Please submit a bug report; see https://gcc.gnu.org/bugs/ . | | Use a subject line meaningful to you and us to track the bug.| | Include the entire contents of this bug box in the report. | | Include the exact command that you entered. | | Also include sources listed below. | +==+ Full build log is at https://buildd.debian.org/status/fetch.php?pkg=ghdl=arm64=3.0.0%2Bdfsg2-1=1696130520=0 I have access to a test machine and an interest to get this package to work, so if there are things I can do to help triaging this, please tell me.
[Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109930 --- Comment #5 from Simon Richter --- > Btw if you know the old state then there is presumably no concurrent access > here and so you don't need atomic, let alone sequential consistency. I know it in some, but not all cases. Basically, what I do is auto old_x = x.load(); retry: switch(old_x) { case 1: if(!x.compare_exchange_weak(old_x, 2)) goto retry; stop_timer(); old_x = x.exchange(4); assert(old_x == 2); break; case 2: // we must have preempted another instance of this function // do nothing break; case 3: // handle timeout ... break; case 4: // handle operation complete ... } This is in code for timeout handling in a realtime system, the timer interrupt can preempt this. State 1 is "operation in progress", state 2 is "operation finished", state 3 is "operation timed out", and state 4 is "operation finished and timer stopped", and the timer interrupt will try to switch from 1 to 3. The transient state 2 then solves the race between the timer expiring and stopping the timer (which is asynchronous because the interrupt controller has a few cycles delay). So the switch from state 2 to state 4 has release semantics.
[Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109930 --- Comment #3 from Simon Richter --- I was looking at ARMv7 initially. If I understood the implementation correctly, this can be a generic optimization.
[Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109930 Bug ID: 109930 Summary: transform atomic exchange to unconditional store when old value is unused? Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- I'm not sure if that is a valid substitution, but... I have a state machine that has a few transitions where I already know the old state, so I can simply do an unconditional store, but I'd also like to have an assertion on the old state in my debug version: std::atomic x; /* ... */ auto old_value = x.exchange(5); assert(old_value == 3); with NDEBUG set, the assert is omitted, and no one is interested in the old value, so the load-with-reserve can be omitted and the store-conditional replaced with a regular store, and this should still be semantically equivalent.
[Bug c++/89564] New: decltype resolution ignores SFINAE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89564 Bug ID: 89564 Summary: decltype resolution ignores SFINAE Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- Similar to #89563, but even more minimal: #include struct one {}; struct two { two() { } two(one const &) { } operator one() const { return one{}; } }; template auto operator+(T const , two const ) -> typename std::enable_if::value, decltype(rhs + lhs)>::type { return rhs + lhs; } void test() { one o; two t; auto a = o + t; } My expectation would be to get a diagnostic that no matching operator+ can be found, both MSVC and icc do this. gcc goes into infinite recursion instantiating the template.
[Bug c++/89563] New: decltype resolution doesn't terminate recursion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89563 Bug ID: 89563 Summary: decltype resolution doesn't terminate recursion Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- Similar to #88176: struct one {}; struct two { two() { } two(one const &) { } operator one() const { return one{}; } two operator+(one const &) const { return two{}; } }; two operator+(two const &, two const &) { return two{}; } template auto operator+(T const , two const ) -> decltype(rhs + lhs) { return rhs + lhs; } void test() { one o; two t; auto a = o + t; } My original expectation would be that this addition resolves to auto operator+(one const , two const ) -> decltype(rhs + lhs); where the decltype is resolved through two two::operator+(one const &) const; This doesn't work, due to #88176, so I've provided a freestanding two operator+(two const &, two const &); which terminates the recursion, forcing a conversion through two::two(one const &); This works fine, except if two::operator one() const; also exists, in which case template recursion again exceeds the maximum depth, so it seems the option to convert the objects back and forth (even though it would never be selected during overload resolution) makes decltype resolution go into the infinite recursion.
[Bug preprocessor/89142] New: Allow poisoning identifier from the command line
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89142 Bug ID: 89142 Summary: Allow poisoning identifier from the command line Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- I'm currently refactoring a program that uses a preprocessor symbol in various places, and I'd like to generate errors for all uses. There is no common header file in which I could place a `#pragma gcc poison` directive, but I can modify the CPPFLAGS globally. It would be nice to have a way to add poisoned preprocessor symbols from the command line.
[Bug c++/88176] New: Overload resolution chooses template non-member operator over non-template member operator
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88176 Bug ID: 88176 Summary: Overload resolution chooses template non-member operator over non-template member operator Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- Similar to #78291: struct foo { foo operator+(foo const ) const { throw; } }; template auto operator+(T const , foo const ) -> decltype(rhs + lhs) { return rhs + lhs; } void test() { foo f1, f2; f1 + f2; } This fails to compile because the template is evaluated recursively. I'd expect the non-template overload to win. MSVC compiles this correctly.
[Bug c++/87634] CSE for dynamic_cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87634 --- Comment #2 from Simon Richter --- Well, I tried really hard to make a case that makes the second dynamic_cast return null after the first returned non-null. The most promising candidate uses a direct destructor call and placement new on a global pointer that happens to be a copy of the pointer passed into the method. struct C : A { virtual void foo() {} }; unsigned char *storage = new unsigned char[std::max(sizeof(B), sizeof(C))]; B *global_b = new(storage) B; later, call test(global_b); and implement B::foo() as global_b->~B(); new(storage) C; If that is legal C++, then rechecking the dynamic type of the object might make sense, but I'm not entirely sure about whether aliasing rules would break that example.
[Bug c++/87634] New: CSE for dynamic_cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87634 Bug ID: 87634 Summary: CSE for dynamic_cast Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- With the code struct A { virtual void foo() = 0; }; struct B : A { virtual void foo() {} void bar() const; }; void test(A *a) { if(auto b = dynamic_cast(a)) b->bar(); if(auto b = dynamic_cast(a)) b->bar(); } I'd expect the type of the object to be unchanged between the two `dynamic_cast` invocations, so the second type check would be unnecessary. The generated code does two checks, however. It is in theory possible to replace the object in-place with one of different type if it is also accessible through a global pointer from within `B::bar()`, but is this a good enough reason to repeat the type check, or would it be possible to optimize out the second dynamic_cast<> here?
[Bug c++/86351] New: Array references as arguments to ternary operator
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86351 Bug ID: 86351 Summary: Array references as arguments to ternary operator Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- The code char const array1[2] = { 'a', 'b' }; char const array2[2] = { 'c', 'd' }; char foo(bool b) { char const ()[2] = b ? array1 : array2; return bar[1]; } is accepted by g++ and rejected by MSVC. My interpretation of the standard would be that MSVC is correct here, as the array decays into a pointer in the ternary operator, but it seems gcc's ternary-as-lvalue extension will also pass array types through ternaries if they are both the same. - Is this intentional? - Will it remain supported? - Can it be turned off somehow?
[Bug tree-optimization/81427] New: Bad optimization for fibonacci function on PowerPC
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81427 Bug ID: 81427 Summary: Bad optimization for fibonacci function on PowerPC Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- Created attachment 41742 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41742=edit Generated assembler code Compiling the code #include uint64_t fib(uint64_t n) { if(n == 0 || n == 1) return n; return fib(n-1) + fib(n-2); } for PowerPC (be/le, 32/64 in any combination) with -O3 gives a lengthy function that is clearly suboptimal (each recursion level saves r14-r31 in a 320 bytes stack frame. The code generated without optimizer looks sane.
[Bug tree-optimization/67886] New: Incomplete optimization for virtual function call into freshly constructed object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67886 Bug ID: 67886 Summary: Incomplete optimization for virtual function call into freshly constructed object Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: Simon.Richter at hogyros dot de Target Milestone: --- This is a bit of a corner/academic case, but came up in a Stack Overflow discussion: struct Base { virtual void func() = 0; }; struct Derived : Base { virtual void func() { }; }; void test() { Base* base = new Derived; for (int i = 0; i < 1000; ++i) { base->func(); } } The generated assembler code on x86_64 with -O3 is Disassembly of section .text: <test()>: 0: 55 push %rbp 1: 53 push %rbx 2: bf 08 00 00 00 mov$0x8,%edi 7: bb e8 03 00 00 mov$0x3e8,%ebx c: 48 83 ec 08 sub$0x8,%rsp 10: e8 00 00 00 00 callq 15 <test()+0x15> 11: R_X86_64_PC32 operator new(unsigned long)-0x4 15: ba 00 00 00 00 mov$0x0,%edx 16: R_X86_64_32 vtable for Derived+0x10 1a: 48 89 c5mov%rax,%rbp 1d: 48 c7 00 00 00 00 00movq $0x0,(%rax) 20: R_X86_64_32Svtable for Derived+0x10 24: eb 13 jmp39 <test()+0x39> 26: 66 2e 0f 1f 84 00 00nopw %cs:0x0(%rax,%rax,1) 2d: 00 00 00 30: 83 eb 01sub$0x1,%ebx 33: 74 1a je 4f <test()+0x4f> 35: 48 8b 55 00 mov0x0(%rbp),%rdx 39: 48 8b 12mov(%rdx),%rdx 3c: 48 81 fa 00 00 00 00cmp$0x0,%rdx 3f: R_X86_64_32SDerived::func() 43: 74 eb je 30 <test()+0x30> 45: 48 89 efmov%rbp,%rdi 48: ff d2 callq *%rdx 4a: 83 eb 01sub$0x1,%ebx 4d: 75 e6 jne35 <test()+0x35> 4f: 48 83 c4 08 add$0x8,%rsp 53: 5b pop%rbx 54: 5d pop%rbp 55: c3 retq Disassembly of section .text._ZN7Derived4funcEv: <Derived::func()>: 0: f3 c3 repz retq This looks like an optimization half-done. The optimizer correctly inlines the function call to Derived::func() into the loop, and also correctly verifies that the function pointer found in the vtable is indeed the same function that was inlined -- otherwise, the inlined function is skipped and the regular function called. I presume that the pointer is rechecked on every loop iteration because it is possible that the function call can destroy the object and create a new one in its place that still derives from Base, so that is correct. If you set -fPIC, the actual values for the vtable pointer and the pointer to Derived::func() are fetched outside of the loop, and rechecked on each loop iteration, again, correctly. However: without -fPIC, there is no way to get a different definition of Derived::func() without invoking UB, so the function pointer check is tautological and can be optimized out, unraveling the entire fuzzy ball, as the inlined function does not destroy the object, and inlining it into the loop should give an empty loop that can be removed. Also, wouldn't setting -fvisibility=hidden also take Derived's symbols out of the dynamic symbol table, in which case I wouldn't be able to override them at runtime with a preload library? The optimal solution from an assembler programmer's perspective would be to take the knowledge that the inlined function does not touch the object's vtable, and create a path that handles the remaining loop iterations after the object was shown to be a Derived object once -- this would probably be optimized to a conditional jump to the ret instruction in the RTL pass -- but I don't have enough knowledge to tell whether that would be easily doable in this case.
[Bug fortran/52347] -Wno-tabs -Wall -Wno-tabs still warns about tabs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52347 Simon Richter Simon.Richter at hogyros dot de changed: What|Removed |Added CC||Simon.Richter at hogyros dot de --- Comment #2 from Simon Richter Simon.Richter at hogyros dot de --- In 4.8, this causes build failures for me: $ g++ -g -Wall -W -Werror -Wno-unused -I. -o stage1/tree_bison_lex.o -c tree_bison_lex.cpp tree_bison_lex.cpp:1744:13: error: unused parameter 'yyscanner' [-Werror=unused-parameter] As can be guessed from the name, this is a file that is generated from flex, which is why I've added -Wno-unused for this file specifically. 4.7 did not warn.
[Bug fortran/52347] -Wno-tabs -Wall -Wno-tabs still warns about tabs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52347 --- Comment #4 from Simon Richter Simon.Richter at hogyros dot de --- Testcase is simple: $ cat tt.cpp void bar(int baz) { } $ g++-4.7 -c -W -Wall -Werror -Wno-unused tt.cpp $ g++-4.8 -c -W -Wall -Werror -Wno-unused tt.cpp tt.cpp:1:6: error: unused parameter ‘baz’ [-Werror=unused-parameter] void bar(int baz) { } ^ cc1plus: all warnings being treated as errors