Hi Steve,
On 7/20/2025 11:06 AM, Steve Kargl wrote:
On Sun, Jul 20, 2025 at 12:39:00AM +0800, Yuao Ma wrote:
On 7/18/2025 11:43 PM, Yuao Ma wrote:
I noticed that hex(16128084538487209988) evaluates to
0xdfd2777000000004, and it looks like the higher bits weren't being
zeroed out as expected. After I explicitly added pos =
convert(gfc_charlen_type_node, pos); for type conversion, the test case
started working perfectly.
I'm sorry, but just adding a cast doesn't solve the issue. Even if we change
the pointer type, we may not be able to alter the memory layout of the input
parameter. Therefore, when accessing the value with a wide type pointer, we
still may not obtain the desired result......
Not sure how to handle this in/out parameter in this case. Maybe the
string_split function in libgfortran should be aware of the integer kind?
No. It should no be aware of integer kind. You need to
deal with this is fortran FE in trans-intrinsics.cc with
appropriate convessations of Fortran INTEGERs to C int
and back.
I believe I have found the correct way to do this. We should modify the
string_split interface to not require passing the pointer. We will
manually convert the argument and return types. It is now able to run
the example in J3/23-007r1. Please review and let me know if this
approach is feasible.
Thanks,
Yuao
* split_1.f90
! { dg-do run }
program b
character(len=:), allocatable :: input
character(len=2) :: set = ', '
integer :: p
input = "one,last example"
p = 0
do
if (p > len(input)) exit
istart = p + 1
call split(input, set, p)
iend = p - 1
print '(T7,A)', input(istart:iend)
end do
end program b
* string_split interface
extern gfc_charlen_type string_split(gfc_charlen_type, const CHARTYPE *,
gfc_charlen_type, const CHARTYPE *,
gfc_charlen_type, GFC_LOGICAL_4);
export_proto(string_split);
* trans-intrinsic.cc(just POC, details need refactor later)
static tree conv_intrinsic_split(gfc_code *code) {
stmtblock_t block;
gfc_se se;
tree stringlen, string;
tree setlen, set;
tree pos, trans_pos, back;
tree tmp;
gfc_start_block(&block);
gfc_init_se(&se, NULL);
gfc_conv_expr(&se, code->ext.actual->expr);
gfc_conv_string_parameter(&se);
stringlen = se.string_length;
gfc_add_block_to_block(&block, &se.pre);
gfc_add_block_to_block(&block, &se.post);
string = se.expr;
gfc_init_se(&se, NULL);
gfc_conv_expr(&se, code->ext.actual->next->expr);
gfc_conv_string_parameter(&se);
setlen = se.string_length;
gfc_add_block_to_block(&block, &se.pre);
gfc_add_block_to_block(&block, &se.post);
set = se.expr;
gfc_init_se(&se, NULL);
gfc_conv_expr(&se, code->ext.actual->next->next->expr);
gfc_add_block_to_block(&block, &se.pre);
gfc_add_block_to_block(&block, &se.post);
pos = se.expr;
trans_pos = fold_convert(gfc_charlen_type_node, pos);
back = build_int_cst(gfc_get_logical_type(4), 0);
tmp = build_call_expr_loc(input_location, gfor_fndecl_string_split, 6,
stringlen, string, setlen, set,
trans_pos, back);
gfc_add_expr_to_block(&block, tmp);
gfc_add_modify(&block, pos,
fold_convert(gfc_typenode_for_spec(
&code->ext.actual->next->next->expr->ts),
tmp));
return gfc_finish_block(&block);
}