https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117302
Bug ID: 117302 Summary: merge + present generates invalid code Product: gcc Version: 14.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: gigor-ads at yandex dot ru Target Milestone: --- Hi! With the following code, GCC generates wrong code: real(8) function test1(a) result(r) implicit none real(8), intent(in), optional :: a r = merge(a, 1.0_8, present(a)) end function test1 With gfortran -O3 it is just test1_: movsd xmm0, QWORD PTR [rdi] ret So, it does not check that present(a) may be false and it put possible inaccessible value a into r, then it leads to SegFaults if a was not present. This code should be semantically as the following: real(8) function test2(a) result(r) implicit none real(8), intent(in), optional :: a if (present(a)) then r = a else r = 1.0_8 end if end function test2 that has a proper assembler with check of present(a): test2_: movsd xmm0, QWORD PTR .LC0[rip] test rdi, rdi je .L3 movsd xmm0, QWORD PTR [rdi] .L3: ret .LC0: .long 0 .long 1072693248 Just note that in some cases, it would be better to set values only after check without setting default value (for simple types it is OK, but not for user-defined). See an example at godbolt: https://godbolt.org/z/969vr763M