aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2012-03-04 21:50:08 +0000
committerMikael Morin <mikael@gcc.gnu.org>2012-03-04 21:50:08 +0000
commit5bf5fa563aea3f8763d2c49d53bf8a0d8c1bc7c2 (patch)
tree7065977b6c71f54588660cd5fd71f801483a0a0b /gcc/fortran
parentf0050a4b2a8ac6d61eeffcac8ad484be9ed462a3 (diff)
downloadgcc-5bf5fa563aea3f8763d2c49d53bf8a0d8c1bc7c2.zip
gcc-5bf5fa563aea3f8763d2c49d53bf8a0d8c1bc7c2.tar.gz
gcc-5bf5fa563aea3f8763d2c49d53bf8a0d8c1bc7c2.tar.bz2
re PR fortran/50981 ([OOP] Wrong-code for scalarizing ELEMENTAL call with absent OPTIONAL argument)
fortran/ PR fortran/50981 * gfortran.h (gfc_is_class_container_ref): New prototype. * class.c (gfc_is_class_container_ref): New function. * trans-expr.c (gfc_conv_procedure_call): Add a "_data" component reference to polymorphic actual arguments. testsuite/ PR fortran/50981 * gfortran.dg/elemental_optional_args_5.f03: Add subcomponent actual argument checks. From-SVN: r184904
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/class.c33
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/trans-expr.c4
4 files changed, 46 insertions, 0 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 005c9bc..8e34526 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,6 +1,14 @@
2012-03-04 Mikael Morin <mikael@gcc.gnu.org>
PR fortran/50981
+ * gfortran.h (gfc_is_class_container_ref): New prototype.
+ * class.c (gfc_is_class_container_ref): New function.
+ * trans-expr.c (gfc_conv_procedure_call): Add a "_data" component
+ reference to polymorphic actual arguments.
+
+2012-03-04 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/50981
* trans-expr.c (gfc_conv_procedure_call): Save se->ss's value.
Handle the case of unallocated arrays passed to elemental procedures.
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index bfa8740..a275136 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -361,6 +361,39 @@ gfc_is_class_scalar_expr (gfc_expr *e)
}
+/* Tells whether the expression E is a reference to a (scalar) class container.
+ Scalar because array class containers usually have an array reference after
+ them, and gfc_fix_class_refs will add the missing "_data" component reference
+ in that case. */
+
+bool
+gfc_is_class_container_ref (gfc_expr *e)
+{
+ gfc_ref *ref;
+ bool result;
+
+ if (e->expr_type != EXPR_VARIABLE)
+ return e->ts.type == BT_CLASS;
+
+ if (e->symtree->n.sym->ts.type == BT_CLASS)
+ result = true;
+ else
+ result = false;
+
+ for (ref = e->ref; ref; ref = ref->next)
+ {
+ if (ref->type != REF_COMPONENT)
+ result = false;
+ else if (ref->u.c.component->ts.type == BT_CLASS)
+ result = true;
+ else
+ result = false;
+ }
+
+ return result;
+}
+
+
/* Build a NULL initializer for CLASS pointers,
initializing the _data component to NULL and
the _vptr component to the declared type. */
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a36e106..d764b62 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2930,6 +2930,7 @@ void gfc_add_class_array_ref (gfc_expr *);
#define gfc_add_def_init_component(e) gfc_add_component_ref(e,"_def_init")
bool gfc_is_class_array_ref (gfc_expr *, bool *);
bool gfc_is_class_scalar_expr (gfc_expr *);
+bool gfc_is_class_container_ref (gfc_expr *e);
gfc_expr *gfc_class_null_initializer (gfc_typespec *);
unsigned int gfc_hash_value (gfc_symbol *);
gfc_try gfc_build_class_symbol (gfc_typespec *, symbol_attribute *,
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 83e3c9c..036b55b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -3542,6 +3542,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
gfc_conv_expr_reference (&parmse, e);
+ if (fsym && fsym->ts.type == BT_DERIVED
+ && gfc_is_class_container_ref (e))
+ parmse.expr = gfc_class_data_get (parmse.expr);
+
/* If we are passing an absent array as optional dummy to an
elemental procedure, make sure that we pass NULL when the data
pointer is NULL. We need this extra conditional because of