The C11 standard appears to imply that iteration statements with constant controlling expressions should not be optimized out. I\'m taking my advice from this answer, which
Just for the record, Clang also misbehaves with goto:
static void die() {
nasty:
goto nasty;
}
int main() {
int x; printf("begin\n");
die();
printf("unreachable\n");
}
It produces the same output as in the question, i.e.:
main: # @main
push rax
mov edi, offset .Lstr
call puts
.Lstr:
.asciz "begin"
I see don't see any way to read this as permitted in C11, which only says:
6.8.6.1(2) A
gotostatement causes an unconditional jump to the statement prefixed by the named label in the enclosing function.
As goto is not an "iteration statement" (6.8.5 lists while, do and for) nothing about the special "termination-assumed" indulgences apply, however you want to read them.
Per original question's Godbolt link compiler is x86-64 Clang 9.0.0 and flags are -g -o output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-9.2.0 -fcolor-diagnostics -fno-crash-diagnostics -O2 -std=c11 example.c
With others such as x86-64 GCC 9.2 you get the pretty well perfect:
.LC0:
.string "begin"
main:
sub rsp, 8
mov edi, OFFSET FLAT:.LC0
call puts
.L2:
jmp .L2
Flags: -g -o output.s -masm=intel -S -fdiagnostics-color=always -O2 -std=c11 example.c