aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-09-26 21:05:44 +0200
committerMartin Liska <mliska@suse.cz>2022-09-26 21:05:44 +0200
commit3c527a35fa428b727807c81f1225a5e0025446c1 (patch)
tree787e21d7bf8a1d85ac7b9ccee784909e85ebf61b /gcc/fortran
parentc9c59aa19c0b7159636763294b7b0c87c696d675 (diff)
parent7701ea4a70a5a5c0fd977da90a30ffc4f3f87617 (diff)
downloadgcc-3c527a35fa428b727807c81f1225a5e0025446c1.zip
gcc-3c527a35fa428b727807c81f1225a5e0025446c1.tar.gz
gcc-3c527a35fa428b727807c81f1225a5e0025446c1.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog116
-rw-r--r--gcc/fortran/expr.cc3
-rw-r--r--gcc/fortran/interface.cc11
-rw-r--r--gcc/fortran/simplify.cc1
-rw-r--r--gcc/fortran/trans-array.cc4
-rw-r--r--gcc/fortran/trans-decl.cc1
-rw-r--r--gcc/fortran/trans-expr.cc83
-rw-r--r--gcc/fortran/trans-types.cc15
-rw-r--r--gcc/fortran/trans.h3
9 files changed, 200 insertions, 37 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f5f8ac0..6985e62 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,119 @@
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ * trans-expr.cc (gfc_conv_procedure_call): Allow strictly
+ matching derived types.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/99169
+ * trans-expr.cc (gfc_conv_procedure_call): Remove conditions
+ on ALLOCATABLE and POINTER attributes guarding clobber
+ generation.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87401
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ disabling clobber generation for ASSOCIATE variables.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ on SAVE attribute guarding clobber generation.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ disabling clobber generation for dummy variables. Remove
+ obsolete comment.
+
+2022-09-25 Harald Anlauf <anlauf@gmx.de>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * trans-expr.cc (gfc_conv_procedure_call): Use dummy
+ information from associated_dummy if there is no information
+ from the procedure interface.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/106817
+ * trans-expr.cc (gfc_conv_procedure_call): Collect all clobbers
+ to their own separate block. Append the block of clobbers to
+ the procedure preliminary block after the argument evaluation
+ codes for all the arguments.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * trans-expr.cc (gfc_conv_procedure_call): Retrieve variable
+ from the just calculated variable reference.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ * trans.h (gfc_conv_expr_reference): Remove add_clobber
+ argument.
+ * trans-expr.cc (gfc_conv_expr_reference): Ditto. Inline code
+ depending on add_clobber and conditions controlling it ...
+ (gfc_conv_procedure_call): ... to here.
+
+2022-09-22 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/100103
+ * trans-array.cc (gfc_is_reallocatable_lhs): Add select rank
+ temporary associate names as possible targets of automatic
+ reallocation.
+
+2022-09-22 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/82868
+ * trans-decl.cc (generate_coarray_sym_init): Skip symbol
+ if attr.associate_var.
+
+2022-09-20 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/104143
+ * interface.cc (compare_parameter): Permit scalar args to
+ 'type(*), dimension(*)'.
+
+2022-09-20 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106986
+ * simplify.cc (gfc_simplify_findloc): Do not try to simplify
+ intrinsic FINDLOC when the ARRAY argument has a NULL shape.
+
+2022-09-20 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106985
+ * expr.cc (gfc_simplify_expr): Avoid NULL pointer dereference.
+
+2022-09-20 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/100132
+ * trans-types.cc (create_fn_spec): Fix function attributes when
+ passing polymorphic pointers.
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ PR fortran/106636
+ * gfortran.texi: Add back link to ISO_VARYING_STRING.
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ * gfortran.texi: Replace "the the" with "the".
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ PR fortran/106636
+ * gfortran.texi: Remove 2 dead links.
+
2022-09-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* libgfortran.h: Declare GFC_FPE_AWAY.
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index be94c18..290ddf3 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -2287,7 +2287,8 @@ gfc_simplify_expr (gfc_expr *p, int type)
initialization expression, or we want a subsection. */
if (p->symtree->n.sym->attr.flavor == FL_PARAMETER
&& (gfc_init_expr_flag || p->ref
- || p->symtree->n.sym->value->expr_type != EXPR_ARRAY))
+ || (p->symtree->n.sym->value
+ && p->symtree->n.sym->value->expr_type != EXPR_ARRAY)))
{
if (!simplify_parameter_variable (p, type))
return false;
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index 71eec78..d3e1995 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -2692,7 +2692,8 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
- if the actual argument is (a substring of) an element of a
non-assumed-shape/non-pointer/non-polymorphic array; or
- (F2003) if the actual argument is of type character of default/c_char
- kind. */
+ kind.
+ - (F2018) if the dummy argument is type(*). */
is_pointer = actual->expr_type == EXPR_VARIABLE
? actual->symtree->n.sym->attr.pointer : false;
@@ -2759,6 +2760,14 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
if (ref == NULL && actual->expr_type != EXPR_NULL)
{
+ if (actual->rank == 0
+ && formal->ts.type == BT_ASSUMED
+ && formal->as
+ && formal->as->type == AS_ASSUMED_SIZE)
+ /* This is new in F2018, type(*) is new in TS29113, but gfortran does
+ not differentiate. Thus, if type(*) exists, it is valid;
+ otherwise, type(*) is already rejected. */
+ return true;
if (where
&& (!formal->attr.artificial || (!formal->maybe_array
&& !maybe_dummy_array_arg (actual))))
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 140c177..c0fbd0e 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -5895,6 +5895,7 @@ gfc_simplify_findloc (gfc_expr *array, gfc_expr *value, gfc_expr *dim,
bool back_val = false;
if (!is_constant_array_expr (array)
+ || array->shape == NULL
|| !gfc_is_constant_expr (dim))
return NULL;
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 0513495..795ce14 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10378,7 +10378,7 @@ gfc_is_reallocatable_lhs (gfc_expr *expr)
/* An allocatable class variable with no reference. */
if (sym->ts.type == BT_CLASS
- && !sym->attr.associate_var
+ && (!sym->attr.associate_var || sym->attr.select_rank_temporary)
&& CLASS_DATA (sym)->attr.allocatable
&& expr->ref
&& ((expr->ref->type == REF_ARRAY && expr->ref->u.ar.type == AR_FULL
@@ -10393,7 +10393,7 @@ gfc_is_reallocatable_lhs (gfc_expr *expr)
/* An allocatable variable. */
if (sym->attr.allocatable
- && !sym->attr.associate_var
+ && (!sym->attr.associate_var || sym->attr.select_rank_temporary)
&& expr->ref
&& expr->ref->type == REF_ARRAY
&& expr->ref->u.ar.type == AR_FULL)
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 908a4c6..5d16d64 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5529,6 +5529,7 @@ generate_coarray_sym_init (gfc_symbol *sym)
if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
|| sym->attr.use_assoc || !sym->attr.referenced
+ || sym->attr.associate_var
|| sym->attr.select_type_temporary)
return;
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 7895d03..4f3ae82 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6018,7 +6018,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_charlen cl;
gfc_expr *e;
gfc_symbol *fsym;
- stmtblock_t post;
enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
gfc_component *comp = NULL;
int arglen;
@@ -6062,7 +6061,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
info = NULL;
+ stmtblock_t post, clobbers;
gfc_init_block (&post);
+ gfc_init_block (&clobbers);
gfc_init_interface_mapping (&mapping);
if (!comp)
{
@@ -6395,7 +6396,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
&& e->symtree->n.sym->attr.pointer))
&& fsym && fsym->attr.target)
/* Make sure the function only gets called once. */
- gfc_conv_expr_reference (&parmse, e, false);
+ gfc_conv_expr_reference (&parmse, e);
else if (e->expr_type == EXPR_FUNCTION
&& e->symtree->n.sym->result
&& e->symtree->n.sym->result != e->symtree->n.sym
@@ -6502,22 +6503,55 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
else
{
- bool add_clobber;
- add_clobber = fsym && fsym->attr.intent == INTENT_OUT
- && !fsym->attr.allocatable && !fsym->attr.pointer
- && e->symtree && e->symtree->n.sym
- && !e->symtree->n.sym->attr.dimension
- && !e->symtree->n.sym->attr.pointer
- && !e->symtree->n.sym->attr.allocatable
- /* See PR 41453. */
- && !e->symtree->n.sym->attr.dummy
- /* FIXME - PR 87395 and PR 41453 */
- && e->symtree->n.sym->attr.save == SAVE_NONE
- && !e->symtree->n.sym->attr.associate_var
- && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
- && e->ts.type != BT_CLASS && !sym->attr.elemental;
-
- gfc_conv_expr_reference (&parmse, e, add_clobber);
+ gfc_conv_expr_reference (&parmse, e);
+
+ gfc_symbol *dsym = fsym;
+ gfc_dummy_arg *dummy;
+
+ /* Use associated dummy as fallback for formal
+ argument if there is no explicit interface. */
+ if (dsym == NULL
+ && (dummy = arg->associated_dummy)
+ && dummy->intrinsicness == GFC_NON_INTRINSIC_DUMMY_ARG
+ && dummy->u.non_intrinsic->sym)
+ dsym = dummy->u.non_intrinsic->sym;
+
+ if (dsym
+ && dsym->attr.intent == INTENT_OUT
+ && !dsym->attr.allocatable
+ && !dsym->attr.pointer
+ && e->expr_type == EXPR_VARIABLE
+ && e->ref == NULL
+ && e->symtree
+ && e->symtree->n.sym
+ && !e->symtree->n.sym->attr.dimension
+ && e->ts.type != BT_CHARACTER
+ && e->ts.type != BT_CLASS
+ && (e->ts.type != BT_DERIVED
+ || (dsym->ts.type == BT_DERIVED
+ && e->ts.u.derived == dsym->ts.u.derived
+ /* Types with allocatable components are
+ excluded from clobbering because we need
+ the unclobbered pointers to free the
+ allocatable components in the callee.
+ Same goes for finalizable types or types
+ with finalizable components, we need to
+ pass the unclobbered values to the
+ finalization routines.
+ For parameterized types, it's less clear
+ but they may not have a constant size
+ so better exclude them in any case. */
+ && !e->ts.u.derived->attr.alloc_comp
+ && !e->ts.u.derived->attr.pdt_type
+ && !gfc_is_finalizable (e->ts.u.derived, NULL)))
+ && !sym->attr.elemental)
+ {
+ tree var;
+ var = build_fold_indirect_ref_loc (input_location,
+ parmse.expr);
+ tree clobber = build_clobber (TREE_TYPE (var));
+ gfc_add_modify (&clobbers, var, clobber);
+ }
}
/* Catch base objects that are not variables. */
if (e->ts.type == BT_CLASS
@@ -7384,6 +7418,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
vec_safe_push (arglist, parmse.expr);
}
+ gfc_add_block_to_block (&se->pre, &clobbers);
gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
if (comp)
@@ -9484,7 +9519,7 @@ gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
values only. */
void
-gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
+gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
{
gfc_ss *ss;
tree var;
@@ -9524,16 +9559,6 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
gfc_add_block_to_block (&se->pre, &se->post);
se->expr = var;
}
- else if (add_clobber && expr->ref == NULL)
- {
- tree clobber;
- tree var;
- /* FIXME: This fails if var is passed by reference, see PR
- 41453. */
- var = expr->symtree->n.sym->backend_decl;
- clobber = build_clobber (TREE_TYPE (var));
- gfc_add_modify (&se->pre, var, clobber);
- }
return;
}
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 0ea7c74..c062a5b 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -3054,12 +3054,23 @@ create_fn_spec (gfc_symbol *sym, tree fntype)
for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
if (spec_len < sizeof (spec))
{
- if (!f->sym || f->sym->attr.pointer || f->sym->attr.target
+ bool is_class = false;
+ bool is_pointer = false;
+
+ if (f->sym)
+ {
+ is_class = f->sym->ts.type == BT_CLASS && CLASS_DATA (f->sym)
+ && f->sym->attr.class_ok;
+ is_pointer = is_class ? CLASS_DATA (f->sym)->attr.class_pointer
+ : f->sym->attr.pointer;
+ }
+
+ if (f->sym == NULL || is_pointer || f->sym->attr.target
|| f->sym->attr.external || f->sym->attr.cray_pointer
|| (f->sym->ts.type == BT_DERIVED
&& (f->sym->ts.u.derived->attr.proc_pointer_comp
|| f->sym->ts.u.derived->attr.pointer_comp))
- || (f->sym->ts.type == BT_CLASS
+ || (is_class
&& (CLASS_DATA (f->sym)->ts.u.derived->attr.proc_pointer_comp
|| CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp))
|| (f->sym->ts.type == BT_INTEGER && f->sym->ts.is_c_interop))
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 03d5288..bc9035c 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -499,8 +499,7 @@ tree gfc_build_compare_string (tree, tree, tree, tree, int, enum tree_code);
void gfc_conv_expr (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_val (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr);
-void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr,
- bool add_clobber = false);
+void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree);