- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Considering the following code:
subroutine test(stat)
implicit none
integer :: stat
if (stat > 0) call abort()
if (stat == 42) print *, 'unreachable'
end subroutine test
which is compiled as follows:
ifx test.f90 -O3 -S
In the resulting code (test.S) I see 'unreachable' string, which should not be there since abort() stops program execution.
Looks like https://llvm.org/docs/LangRef.html#unreachable-instruction is not generated after exit/abort calls. error-stop-stmt/stop-stmt do not have this problem.
Tested with ifx 2025.2.1.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
EXIT is a non-standard intrinsic subroutine. Intrinsic means that the compiler knows about it, but there's no requirement that the code generator be aware that it never returns. If you care about such things, use ERROR STOP.
Link kopiert
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
The compiler has the option that stat < 0 so the first if fails, the second if then checks , it is reached it just takes the false line and then proceeds on.
Nothing strange.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
It says the string "unreachable" can be found in the assembler, not that it is written to the screen. Of course the compiler can stick whatever it wants in the assembler so long as the program when executed behave as prescribed by the standard.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
The compiler has no idea what ABORT does - it's not part of the Fortran language. In this case it's just some procedure defined in a non-intrinsic module.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
There are a couple of issues here, not the least of which is that you did not provide a complete program. The other major issue is that your code is incorrect.
If I use the following program:
program foo
call test_quiet (42)
end
subroutine test_quiet(stat)
use ifport, only: abort
implicit none
integer :: stat
if (stat > 0) call abort()
if (stat == 42) print *, 'unreachable'
end subroutine test_quietIt works as I would expect and delivers:
D:\Projects>t.exe
abort: Fortran Abort Calledand nothing else. But without the USE IFPORT, as you had, you lose the explicit interface required for omitting an optional argument, and the results are unpredictable (I got an access violation in one scenario.)
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
> The compiler has no idea what ABORT does - it's not part of the Fortran language.
Yep, it is a compiler extension that requires explicit interface. However, once interface is known, compiler also knows what this routine do and then can insert unreachable after `call ABORT` to avoid generation of PRINT *, 'unreachable' code.
Probably, it is a good idea here to propose a FINAL keyword (or another name) for subroutines that never return control, so compilers will know more about execution of such routines without looking on their implementation.
EXIT is also a compiler extension, however looks like it does not require explicit interface:
https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2023-2/exit-subroutine.html
which translates to `for_exit@PLT` call. So, it seems to me that `unreachable` may be put after for_exit call to avoid generation of PRINT *, 'unreachable' code. (42 is positive, but any positive number are not possible after non-returning exit call)
If it had to be `call exit_@PLT`, user would be able to redefine exit routine and insertion of `unreachable` would be dangerous.
The ASM for call exit:
.file "test.f90"
.text
.globl test_quiet_
.p2align 4
.type test_quiet_,@function
test_quiet_:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
subq $96, %rsp
.cfi_def_cfa_offset 112
.cfi_offset %rbx, -16
movl (%rdi), %ebx
testl %ebx, %ebx
jle .LBB0_3
movl $__unnamed_1, %edi
callq for_exit@PLT ; <- call exit
cmpl $42, %ebx
jne .LBB0_3
movq $0, 32(%rsp)
movl $66616, 12(%rsp)
movq $11, 16(%rsp)
movq $strlit, 24(%rsp) ; <- loading of 'unreachable'
leaq 32(%rsp), %rdi
movabsq $2253038970797824, %rdx
leaq 12(%rsp), %rcx
leaq 16(%rsp), %r8
movl $-1, %esi
xorl %eax, %eax
callq for_write_seq_lis@PLT
.LBB0_3:
addq $96, %rsp
.cfi_def_cfa_offset 16
popq %rbx
.cfi_def_cfa_offset 8
retq
.Lfunc_end0:
.size test_quiet_, .Lfunc_end0-test_quiet_
.cfi_endproc
.type strlit,@object
.section .rodata,"a",@progbits
strlit:
.ascii "unreachable"
.size strlit, 11
.type __unnamed_1,@object
.section .rodata.cst4,"aM",@progbits,4
.p2align 2, 0x0
__unnamed_1:
.long 0
.size __unnamed_1, 4
.section ".note.GNU-stack","",@progbits
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
EXIT is a non-standard intrinsic subroutine. Intrinsic means that the compiler knows about it, but there's no requirement that the code generator be aware that it never returns. If you care about such things, use ERROR STOP.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
It's worth remembering that all ASCII strings are stored in plain text within the executable code. No good if you're trying to store a password to prevent unauthorised execution of the code!
- RSS-Feed abonnieren
- Thema als neu kennzeichnen
- Thema als gelesen kennzeichnen
- Diesen Thema für aktuellen Benutzer floaten
- Lesezeichen
- Abonnieren
- Drucker-Anzeigeseite