[Bug fortran/32732] [Bind C] Character scalars are passed as arrays
Christopher D. Rickett
crickett@lanl.gov
Fri Aug 3 19:55:00 GMT 2007
:ADDPATCH fortran:
the patch is attached. bootstrapped and regtested on x86 and x86_64 linux
with no new failures.
ChangeLog entry:
2007-08-03 Christopher D. Rickett <crickett@lanl.gov>
PR fortran/32732
* trans-expr.c (gfc_conv_scalar_char_value): Convert the tree and
actual arg expressions for scalar characters passed by-value to
bind(c) routines.
(gfc_conv_function_call): Call gfc_conv_scalar_char_value.
* trans.h: Add prototype for gfc_conv_scalar_char_value.
* trans-decl.c (generate_local_decl): Convert by-value character
dummy args of bind(c) procedures using
gfc_conv_scalar_char_value.
Chris
On Fri, 3 Aug 2007, Christopher D. Rickett wrote:
>
>
>> My IA64 HP-UX and Linux runs look good too. c_kind_params.f90 fails to
>> compile on my HPPA HP-UX platforms but that is probably due to HPPA's
>> incomplete support for C99 and not defining the __int64_t type. I will
>> look into how to fix that, but I don't see any runtime problems or
>> regressions so I think the patch should be checked in.
>>
>> Thanks a lot for for all your work in coming up with this fix.
>>
>
> thanks for all of your testing and debugging help. i'll submit a patch later
> today.
>
> Chris
>
-------------- next part --------------
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c (revision 127182)
+++ gcc/fortran/trans-expr.c (working copy)
@@ -1209,6 +1209,59 @@ gfc_to_single_character (tree len, tree
return NULL_TREE;
}
+
+void
+gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
+{
+ gfc_expr *tmp_expr;
+
+ if (sym->backend_decl)
+ {
+ /* This becomes the nominal_type in
+ function.c:assign_parm_find_data_types. */
+ TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
+ /* This becomes the passed_type in
+ function.c:assign_parm_find_data_types. C promotes char to
+ integer for argument passing. */
+ DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
+
+ DECL_BY_REFERENCE (sym->backend_decl) = 0;
+ }
+
+ if (expr != NULL)
+ {
+ /* If we have a constant character expression, make it into an
+ integer. */
+ if ((*expr)->expr_type == EXPR_CONSTANT)
+ {
+ tmp_expr = *expr;
+ *expr = gfc_int_expr ((int)tmp_expr->value.character.string[0]);
+ }
+ else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
+ {
+ if ((*expr)->ref == NULL)
+ {
+ tmp_expr = *expr;
+ se->expr = gfc_to_single_character
+ (build_int_cst (integer_type_node, 1),
+ gfc_build_addr_expr (pchar_type_node,
+ gfc_get_symbol_decl
+ ((*expr)->symtree->n.sym)));
+ }
+ else
+ {
+ gfc_conv_variable (se, *expr);
+ se->expr = gfc_to_single_character
+ (build_int_cst (integer_type_node, 1),
+ gfc_build_addr_expr (pchar_type_node, se->expr));
+ }
+ }
+ }
+
+ return;
+}
+
+
/* Compare two strings. If they are all single characters, the result is the
subtraction of them. Otherwise, we build a library call. */
@@ -2166,7 +2219,18 @@ gfc_conv_function_call (gfc_se * se, gfc
{
if (fsym && fsym->attr.value)
{
- gfc_conv_expr (&parmse, e);
+ if (fsym->ts.type == BT_CHARACTER
+ && fsym->ts.is_c_interop
+ && fsym->ns->proc_name != NULL
+ && fsym->ns->proc_name->attr.is_bind_c)
+ {
+ parmse.expr = NULL;
+ gfc_conv_scalar_char_value (fsym, &parmse, &e);
+ if (parmse.expr == NULL)
+ gfc_conv_expr (&parmse, e);
+ }
+ else
+ gfc_conv_expr (&parmse, e);
}
else if (arg->name && arg->name[0] == '%')
/* Argument list functions %VAL, %LOC and %REF are signalled
Index: gcc/fortran/trans.h
===================================================================
--- gcc/fortran/trans.h (revision 127182)
+++ gcc/fortran/trans.h (working copy)
@@ -295,6 +295,9 @@ void gfc_conv_expr_lhs (gfc_se * se, gfc
void gfc_conv_expr_reference (gfc_se * se, gfc_expr *);
void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree);
+/* trans-expr.c */
+void gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr);
+
/* Find the decl containing the auxiliary variables for assigned variables. */
void gfc_conv_label_variable (gfc_se * se, gfc_expr * expr);
/* If the value is not constant, Create a temporary and copy the value. */
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c (revision 127182)
+++ gcc/fortran/trans-decl.c (working copy)
@@ -3047,7 +3047,7 @@ generate_local_decl (gfc_symbol * sym)
if (sym->attr.value == 1 && sym->backend_decl != NULL
&& sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
&& sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
- TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
+ gfc_conv_scalar_char_value (sym, NULL, NULL);
}
/* Make sure we convert the types of the derived types from iso_c_binding
More information about the Fortran
mailing list