aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2019-04-14 18:14:58 +0000
committerPaul Thomas <pault@gcc.gnu.org>2019-04-14 18:14:58 +0000
commit0d78e4aa06db041ef895c7153c1380baff53e434 (patch)
treeff263942aea3fd3887c7ff230766d23b43e55cae /gcc/fortran/trans-decl.c
parent4d024c32696b98f3ca15505fbaa39600d7c118bb (diff)
downloadgcc-0d78e4aa06db041ef895c7153c1380baff53e434.zip
gcc-0d78e4aa06db041ef895c7153c1380baff53e434.tar.gz
gcc-0d78e4aa06db041ef895c7153c1380baff53e434.tar.bz2
re PR fortran/89843 (CFI_section delivers incorrect result descriptor)
2019-04-14 Paul Thomas <pault@gcc.gnu.org> 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 <pault@gcc.gnu.org> 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 <pault@gcc.gnu.org> 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. From-SVN: r270353
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index ada6370..a0e1f6a 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -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
@@ -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);