https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112870
Bug ID: 112870
Summary: incorrect jmp when using goto on a function, causing
infinite loop
Product: gcc
Version: 13.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: grantrwittmann at gmail dot com
Target Milestone: ---
When first setting a variable to a label, then jumping after that label to a
function (not calling the function), GCC generates incorrect assembly causing
the goto statement to jump to the previous label and not the function.
The code:
void function() {
return;
}
int main() {
void* label_var = &&label;
label:
goto *&function;
}
compiles to this assembly:
function:
push rbp
mov rbp, rsp
nop
pop rbp
ret
main:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], OFFSET FLAT:.L4
.L4:
nop
jmp .L4
The last jmp goes back to .L4 (label) even though it should be going to
function. The assembly is compiled correctly when the `label_var` declaration
is removed.
This same code compiles correctly on other compilers like clang (17.0.1):
function: # @function
push rbp
mov rbp, rsp
pop rbp
ret
main: # @main
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], 0
lea rax, [rip + .Ltmp2]
mov qword ptr [rbp - 16], rax
.Ltmp2: # Block address taken
.LBB1_1: # =>This Inner Loop Header: Depth=1
lea rax, [rip + function]
mov qword ptr [rbp - 24], rax # 8-byte Spill
jmp .LBB1_2
.LBB1_2: # in Loop: Header=BB1_1 Depth=1
mov rax, qword ptr [rbp - 24] # 8-byte Reload
jmp rax
All examples from this issue were compiled and ran through the godbolt.org
online compiler explorer.