Hi Yuao,

Yuao Ma wrote:
On Tue, Sep 16, 2025 at 5:11 PM Tobias Burnus<[email protected]> wrote:
PS: Already with the current code, we may run into the issue of passing
an actual argument like '(cond ? "abc" : "cdfg")' to 'class(*)' – and I
am not sure whether we handle this correctly or not.
That is a great test case, and I apologize for not testing against the
cond-arg part. The current patch doesn't work well with cond-arg,
whether or not class(*) is involved. To avoid introducing new ICE,
I'll hold off on this patch until we can properly use character types
in both cond-expr and cond-arg. Part of the root of the problem seems
to be 
here:https://github.com/gcc-mirror/gcc/blob/857c742e7bb8b24a05180e1cfee62efa417a48fe/gcc/fortran/trans-expr.cc#L10652.
When the expression's type is found to be a character, it uses
gfc_conv_string_parameter and returns immediately. Handling
EXPR_CONDITIONAL first would solve part of the issue, allowing two
character variables to be passed without a problem. However, passing
two STRING_CST still causes an ICE, failing in fold_convert_loc within
GIMPLE. I'm currently investigating why this is happening.

If you want me to have a look as well, it helps if you sent a minimal patch plus example. Otherwise, I quickly acknowledge that there is an issue – without knowing much more nor digging into it.

Regarding the const, I wonder whether something gets wrong with the type declaration?

* * *

2: Disallow nil for Non-Optional Dummy Arguments
If a dummy argument isn't declared with the OPTIONAL attribute, nil
shouldn't be allowed as an actual argument. I think the ideal place
for this check is in compare_actual_formal, where we can raise an
error if the formal argument lacks the OPTIONAL attribute and the
actual argument is nil. The challenge is figuring out how to store the
information that an inner cond-expr contains a nil branch. I haven't
found a clean solution yet. Perhaps adding a new field to the AST
could work? You previously mentioned using do_not_resolve_again to
move the check to the optional checking part. Could you elaborate more
on this?

I think compare_actual_formal should mostly work, the problem is only all code that bypasses it. I think several intrinsic functions skip this – but on the other hand, while "Many of the intrinsic procedures have optional arguments", several require "a scalar integer constant expression" - which '.nil.' isn't.

For resolving, I was wondering whether we can pass a special flag on to simplify_conditional – which tells whether being in an actual-argument resolution or not. — .nil. can only occur when the expression is a EXPR_CONDITIONAL but not deeply nested in any other expression. – But for 'stat' it seems as if '.nil.' could be valid.

NOTE: For optional+value, we need to be careful because the present status is passed as additional hidden argument.

* * *

3: Restrict nil only in cond-arg
nil shouldn't appear in a regular cond-expr outside of an argument
list. The problem is differentiating between when gfc_resolve_expr is
resolving a function argument versus an ordinary expression. The
former is called from resolve_actual_arglist, but I haven't found a
way to distinguish between these two contexts yet.

What I was thinking of is something like the following in
resolve_actual_arglist: if (e->expr_type == EXPR_CONDITIONAL) 
simplify_conditional (e, /* is_actual_arg = */ true, is_optional);else 
gfc_resolve_expr ();

And handle in this case the resolution of the condition + true / false
branch also inside the called function (simplify_conditional
or a different function) + setting e->do_not_resolve_again = true
afterwards. If the true or false expression is itself EXPR_CONDITIONAL
it is handled recursively.

If simplify_conditional is called any other way, which includes
code like 'call f( ( (cond ? a : b) ) )' (extra '()')
or 'call f( (cond ? a : b) + 1)', is_actual_arg is false and
.nil. can be rejected.

That's somewhat independent from how we handle .nil. I think
we have come up with several ways, all having its pro and cons.
For instance: Adding a new EXPR_OP operator, which operates on 0
expressions (expr1 == expr2 == 0), contrary to .not. (one) or
.and. (two).

Or your proposal of having a EXPR_CONDITIONAL with true = false = condition = 
NULL.

Or ...

* * *

Tobias

PS: Still a quickly written email and not in depth.

Reply via email to