Skip to content

Commit

Permalink
2019-04-14 Paul Thomas <[email protected]>
Browse files Browse the repository at this point in the history
	PR fortran/89843
	* trans-decl.c (gfc_get_symbol_decl): Assumed shape and assumed
	rank dummies of bind C procs require deferred initialization.
	(convert_CFI_desc): New procedure to convert incoming CFI
	descriptors to gfc types and back again.
	(gfc_trans_deferred_vars): Call it.
	* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Null the CFI
	descriptor pointer. Free the descriptor in all cases.

	PR fortran/89846
	* expr.c (is_CFI_desc): New function.
	(is_subref_array): Tidy up by referencing the symbol directly.
	* gfortran.h : Prototype for is_CFI_desc.
	* trans_array.c (get_CFI_desc): New function.
	(gfc_get_array_span, gfc_conv_scalarized_array_ref,
	gfc_conv_array_ref): Use it.
	* trans.c (get_array_span): Extract the span from descriptors
	that are indirect references.

	PR fortran/90022
	* trans-decl.c (gfc_get_symbol_decl): Make sure that the se
	expression is a pointer type before converting it to the symbol
	backend_decl type.
	* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Eliminate
	temporary creation for intent(in).

2019-04-14  Paul Thomas  <[email protected]>

	PR fortran/89843
	* gfortran.dg/ISO_Fortran_binding_4.f90: Modify the value of x
	in ctg. Test the conversion of the descriptor types in the main
	program.
	* gfortran.dg/ISO_Fortran_binding_10.f90: New test.
	* gfortran.dg/ISO_Fortran_binding_10.c: Called by it.

	PR fortran/89846
	* gfortran.dg/ISO_Fortran_binding_11.f90: New test.
	* gfortran.dg/ISO_Fortran_binding_11.c: Called by it.

	PR fortran/90022
	* gfortran.dg/ISO_Fortran_binding_1.c: Correct the indexing for
	the computation of 'ans'. Also, change the expected results for
	CFI_is_contiguous to comply with standard.
	* gfortran.dg/ISO_Fortran_binding_1.f90: Correct the expected
	results for CFI_is_contiguous to comply with standard.
	* gfortran.dg/ISO_Fortran_binding_9.f90: New test.
	* gfortran.dg/ISO_Fortran_binding_9.c: Called by it.

2019-04-14  Paul Thomas  <[email protected]>

	PR fortran/89843
	* runtime/ISO_Fortran_binding.c (cfi_desc_to_gfc_desc): Only
	return immediately if the source pointer is null. Bring
	forward the extraction of the gfc type. Extract the kind so
	that the element size can be correctly computed for sections
	and components of derived type arrays. Remove the free of the
	CFI descriptor since this is now done in trans-expr.c.
	(gfc_desc_to_cfi_desc): Only allocate the CFI descriptor if it
	is not null.
	(CFI_section): Normalise the difference between the upper and
	lower bounds by the stride to correctly calculate the extents
	of the section.

	PR fortran/89846
	* runtime/ISO_Fortran_binding.c (cfi_desc_to_gfc_desc): Use
	the stride measure for the gfc span if it is not a multiple
	of the element length. Otherwise use the element length.

	PR fortran/90022
	* runtime/ISO_Fortran_binding.c (CFI_is_contiguous) : Return
	1 for true and 0 otherwise to comply with the standard. Correct
	the contiguity check for rank 3 and greater by using the stride
	measure of the lower dimension rather than the element length.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270353 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
pault committed Apr 14, 2019
1 parent 7799988 commit 37684a4
Show file tree
Hide file tree
Showing 20 changed files with 680 additions and 159 deletions.
28 changes: 28 additions & 0 deletions gcc/fortran/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
2019-04-14 Paul Thomas <[email protected]>

PR fortran/89843
* trans-decl.c (gfc_get_symbol_decl): Assumed shape and assumed
rank dummies of bind C procs require deferred initialization.
(convert_CFI_desc): New procedure to convert incoming CFI
descriptors to gfc types and back again.
(gfc_trans_deferred_vars): Call it.
* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Null the CFI
descriptor pointer. Free the descriptor in all cases.

PR fortran/89846
* expr.c (is_CFI_desc): New function.
(is_subref_array): Tidy up by referencing the symbol directly.
* gfortran.h : Prototype for is_CFI_desc.
* trans_array.c (get_CFI_desc): New function.
(gfc_get_array_span, gfc_conv_scalarized_array_ref,
gfc_conv_array_ref): Use it.
* trans.c (get_array_span): Extract the span from descriptors
that are indirect references.

PR fortran/90022
* trans-decl.c (gfc_get_symbol_decl): Make sure that the se
expression is a pointer type before converting it to the symbol
backend_decl type.
* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Eliminate
temporary creation for intent(in).

2019-04-13 Dominique d'Humieres <[email protected]>

PR fortran/79842
Expand Down
34 changes: 29 additions & 5 deletions gcc/fortran/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,18 +1061,42 @@ gfc_is_constant_expr (gfc_expr *e)
}


/* Is true if the expression or symbol is a passed CFI descriptor. */
bool
is_CFI_desc (gfc_symbol *sym, gfc_expr *e)
{
if (sym == NULL
&& e && e->expr_type == EXPR_VARIABLE)
sym = e->symtree->n.sym;

if (sym && sym->attr.dummy
&& sym->ns->proc_name->attr.is_bind_c
&& sym->attr.dimension
&& (sym->attr.pointer
|| sym->attr.allocatable
|| sym->as->type == AS_ASSUMED_SHAPE
|| sym->as->type == AS_ASSUMED_RANK))
return true;

return false;
}


/* Is true if an array reference is followed by a component or substring
reference. */
bool
is_subref_array (gfc_expr * e)
{
gfc_ref * ref;
bool seen_array;
gfc_symbol *sym;

if (e->expr_type != EXPR_VARIABLE)
return false;

if (e->symtree->n.sym->attr.subref_array_pointer)
sym = e->symtree->n.sym;

if (sym->attr.subref_array_pointer)
return true;

seen_array = false;
Expand All @@ -1097,10 +1121,10 @@ is_subref_array (gfc_expr * e)
return seen_array;
}

if (e->symtree->n.sym->ts.type == BT_CLASS
&& e->symtree->n.sym->attr.dummy
&& CLASS_DATA (e->symtree->n.sym)->attr.dimension
&& CLASS_DATA (e->symtree->n.sym)->attr.class_pointer)
if (sym->ts.type == BT_CLASS
&& sym->attr.dummy
&& CLASS_DATA (sym)->attr.dimension
&& CLASS_DATA (sym)->attr.class_pointer)
return true;

return false;
Expand Down
1 change: 1 addition & 0 deletions gcc/fortran/gfortran.h
Original file line number Diff line number Diff line change
Expand Up @@ -3221,6 +3221,7 @@ gfc_actual_arglist *gfc_copy_actual_arglist (gfc_actual_arglist *);
bool gfc_extract_int (gfc_expr *, int *, int = 0);
bool gfc_extract_hwi (gfc_expr *, HOST_WIDE_INT *, int = 0);

bool is_CFI_desc (gfc_symbol *, gfc_expr *);
bool is_subref_array (gfc_expr *);
bool gfc_is_simply_contiguous (gfc_expr *, bool, bool);
bool gfc_is_not_contiguous (gfc_expr *);
Expand Down
54 changes: 51 additions & 3 deletions gcc/fortran/trans-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,16 +849,56 @@ is_pointer_array (tree expr)
}


/* If the symbol or expression reference a CFI descriptor, return the
pointer to the converted gfc descriptor. If an array reference is
present as the last argument, check that it is the one applied to
the CFI descriptor in the expression. Note that the CFI object is
always the symbol in the expression! */

static bool
get_CFI_desc (gfc_symbol *sym, gfc_expr *expr,
tree *desc, gfc_array_ref *ar)
{
tree tmp;

if (!is_CFI_desc (sym, expr))
return false;

if (expr && ar)
{
if (!(expr->ref && expr->ref->type == REF_ARRAY)
|| (&expr->ref->u.ar != ar))
return false;
}

if (sym == NULL)
tmp = expr->symtree->n.sym->backend_decl;
else
tmp = sym->backend_decl;

if (tmp && DECL_LANG_SPECIFIC (tmp))
tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);

*desc = tmp;
return true;
}


/* Return the span of an array. */

tree
gfc_get_array_span (tree desc, gfc_expr *expr)
{
tree tmp;

if (is_pointer_array (desc))
/* This will have the span field set. */
tmp = gfc_conv_descriptor_span_get (desc);
if (is_pointer_array (desc) || get_CFI_desc (NULL, expr, &desc, NULL))
{
if (POINTER_TYPE_P (TREE_TYPE (desc)))
desc = build_fold_indirect_ref_loc (input_location, desc);

/* This will have the span field set. */
tmp = gfc_conv_descriptor_span_get (desc);
}
else if (TREE_CODE (desc) == COMPONENT_REF
&& GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
&& GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (desc, 0))))
Expand Down Expand Up @@ -3466,6 +3506,12 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
if (build_class_array_ref (se, base, index))
return;

if (get_CFI_desc (NULL, expr, &decl, ar))
{
decl = build_fold_indirect_ref_loc (input_location, decl);
goto done;
}

if (expr && ((is_subref_array (expr)
&& GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor)))
|| (expr->ts.deferred && (expr->expr_type == EXPR_VARIABLE
Expand Down Expand Up @@ -3721,6 +3767,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
/* A pointer array component can be detected from its field decl. Fix
the descriptor, mark the resulting variable decl and pass it to
build_array_ref. */
if (get_CFI_desc (sym, expr, &decl, ar))
decl = build_fold_indirect_ref_loc (input_location, decl);
if (!expr->ts.deferred && !sym->attr.codimension
&& is_pointer_array (se->expr))
{
Expand Down
73 changes: 73 additions & 0 deletions gcc/fortran/trans-decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4268,6 +4268,72 @@ gfc_null_and_pass_deferred_len (gfc_symbol *sym, stmtblock_t *init,
}


/* Convert CFI descriptor dummies into gfc types and back again. */
static void
convert_CFI_desc (gfc_wrapped_block * block, gfc_symbol *sym)
{
tree gfc_desc;
tree gfc_desc_ptr;
tree CFI_desc;
tree CFI_desc_ptr;
tree dummy_ptr;
tree tmp;
tree incoming;
tree outgoing;
stmtblock_t tmpblock;

/* dummy_ptr will be the pointer to the passed array descriptor,
while CFI_desc is the descriptor itself. */
if (DECL_LANG_SPECIFIC (sym->backend_decl))
CFI_desc = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl);
else
CFI_desc = NULL;

dummy_ptr = CFI_desc;

if (CFI_desc)
{
CFI_desc = build_fold_indirect_ref_loc (input_location, CFI_desc);

/* The compiler will have given CFI_desc the correct gfortran
type. Use this new variable to store the converted
descriptor. */
gfc_desc = gfc_create_var (TREE_TYPE (CFI_desc), "gfc_desc");
tmp = build_pointer_type (TREE_TYPE (gfc_desc));
gfc_desc_ptr = gfc_create_var (tmp, "gfc_desc_ptr");
CFI_desc_ptr = gfc_create_var (pvoid_type_node, "CFI_desc_ptr");

gfc_init_block (&tmpblock);
/* Pointer to the gfc descriptor. */
gfc_add_modify (&tmpblock, gfc_desc_ptr,
gfc_build_addr_expr (NULL, gfc_desc));
/* Store the pointer to the CFI descriptor. */
gfc_add_modify (&tmpblock, CFI_desc_ptr,
fold_convert (pvoid_type_node, dummy_ptr));
tmp = gfc_build_addr_expr (ppvoid_type_node, CFI_desc_ptr);
/* Convert the CFI descriptor. */
incoming = build_call_expr_loc (input_location,
gfor_fndecl_cfi_to_gfc, 2, gfc_desc_ptr, tmp);
gfc_add_expr_to_block (&tmpblock, incoming);
/* Set the dummy pointer to point to the gfc_descriptor. */
gfc_add_modify (&tmpblock, dummy_ptr,
fold_convert (TREE_TYPE (dummy_ptr), gfc_desc_ptr));
incoming = gfc_finish_block (&tmpblock);

gfc_init_block (&tmpblock);
/* Convert the gfc descriptor back to the CFI type before going
out of scope. */
tmp = gfc_build_addr_expr (ppvoid_type_node, CFI_desc_ptr);
outgoing = build_call_expr_loc (input_location,
gfor_fndecl_gfc_to_cfi, 2, tmp, gfc_desc_ptr);
gfc_add_expr_to_block (&tmpblock, outgoing);
outgoing = gfc_finish_block (&tmpblock);

/* Add the lot to the procedure init and finally blocks. */
gfc_add_init_cleanup (block, incoming, outgoing);
}
}

/* Get the result expression for a procedure. */

static tree
Expand Down Expand Up @@ -4844,6 +4910,13 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
}
else if (!(UNLIMITED_POLY(sym)) && !is_pdt_type)
gcc_unreachable ();

/* Assumed shape and assumed rank arrays are passed to BIND(C) procedures
as ISO Fortran Interop descriptors. These have to be converted to
gfortran descriptors and back again. This has to be done here so that
the conversion occurs at the start of the init block. */
if (is_CFI_desc (sym, NULL))
convert_CFI_desc (block, sym);
}

gfc_init_block (&tmpblock);
Expand Down
Loading

0 comments on commit 37684a4

Please sign in to comment.