[Bug c++/114675] New: warning for "reference to not fully constructed object"

2024-04-10 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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

2024-02-18 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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

2024-02-18 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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

2023-10-05 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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?

2023-05-31 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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?

2023-05-22 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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?

2023-05-22 Thread Simon.Richter at hogyros dot de via Gcc-bugs
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

2019-03-02 Thread Simon.Richter at hogyros dot de
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

2019-03-02 Thread Simon.Richter at hogyros dot de
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

2019-01-31 Thread Simon.Richter at hogyros dot de
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

2018-11-23 Thread Simon.Richter at hogyros dot de
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

2018-10-18 Thread Simon.Richter at hogyros dot de
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

2018-10-17 Thread Simon.Richter at hogyros dot de
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

2018-06-28 Thread Simon.Richter at hogyros dot de
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

2017-07-13 Thread Simon.Richter at hogyros dot de
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

2015-10-07 Thread Simon.Richter at hogyros dot de
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

2013-06-14 Thread Simon.Richter at hogyros dot de
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

2013-06-14 Thread Simon.Richter at hogyros dot de
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