[PATCH] fortran: allow character in conditional expression

Tobias Burnus tburnus@baylibre.com
Mon Sep 22 07:47:08 GMT 2025


Hi Yuao,

Yuao Ma wrote:
> I've made two key updates in this version:
> 1. In gfc_conv_expr_reference, the previous logic handled BT_CHARACTER
> first. This caused a failure when we had a cond-arg with a character
> type, as the cond-expr logic wasn't being handled correctly. I've
> simply reordered the check case to handle the cond-expr first.
> 2. The previous gfc_conv_constant function didn't handle want_pointer,
> whereas gfc_conv_variable did. This explains why two string variables
> worked correctly, but two string constants resulted in an ICE.

Thanks for the updated patch. Glancing at the code, I wondered about:

+  if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))

Namely: Why are procedure-pointer components handled differently?

I have still to understand that part, but I created a testcase that
fails in "force_constant_size, at gimplify.cc:809"

--------------------------------------
implicit none (type, external)

character(len=:), allocatable :: str
integer :: i

do i = 1, 3
   str =  (i > 1 ? f() : "abcd")
   print '(*(g0))', len(str), " >",str,"<"
end do

contains
  function f()
    character(:), allocatable :: f
    if (i == 1) then
      f = "12345"
    else
      f = ""
    end if
  end
end
--------------------------------------

The following looks odd:

   D.4706 = (void *) &(D.4698 ? pstr.1 : "abcd");

The '&' looks wrong; at least 'pstr.1' is already a pointer,
for "abcd", I am currently sure how it should look in the
dump (in C/C++ is clear). gfortran produces without a
conditional:
   &"abcd"[1]


And the following testcase fails elsewhere during
gimplification:  in create_tmp_var, at gimple-expr.cc:484

--------------------------------------
implicit none (type, external)

character(len=:), allocatable :: str
integer :: i
character(len=5) :: str2 = "ABCDE"

   str =  (i > 1 ? "abcde" : str2(1:3))
end
--------------------------------------

Actually, while the error message is different, the
dump shows the same issue:
     D.4683 = (void *) &(D.4678 ? "abcde" : &str2);

why is there an '&' before '('?

Tobias

PS: Sorry for the belated reply and still not doing a proper
review but just glancing at the code.
BTW: Using  "abc"(1:i) or str(i:5) similar substrings, it is possible
to combine a constant string or const-length variable with not knowing
the length address of the  in the expression - including also changing
the first character picked from the string.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/fortran/attachments/20250922/5db861ea/attachment.htm>


More information about the Fortran mailing list