Hi Tobias,

On Mon, Sep 22, 2025 at 3:47 PM Tobias Burnus <[email protected]> wrote:
> 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 must admit that I borrowed this code snippet from gfc_conv_variable.
I am unsure if gfc_is_proc_ptr_comp is appropriate here, so I included
it to keep them consistent.

> 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 '('?
>

Thanks for providing those test cases! They helped me see the real
issue. The problem is that most of the existing character arguments
are handled directly within gfc_conv_string_parameter. This means even
when I reordered the expr types in gfc_conv_expr_reference, I was
still missing cases like the ones you found.
So, I've taken a different approach: for character types, I'm now
handling the cond-expr directly inside gfc_conv_string_parameter. This
involves recursively calling the function for both the lse and rse.
The failed test cases now work with this patch.

>
> 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.

I have tested "abc"(1:i) pattern in my latest patch and it works as expected.

Yuao

PS: Sorry for the late reply! I had some urgent stuff come up that ate
most of my time. : (

Attachment: 0001-fortran-allow-character-in-conditional-expression.patch
Description: Binary data

Reply via email to