diff options
author | Mikael Morin <mikael@gcc.gnu.org> | 2012-03-04 21:50:08 +0000 |
---|---|---|
committer | Mikael Morin <mikael@gcc.gnu.org> | 2012-03-04 21:50:08 +0000 |
commit | 5bf5fa563aea3f8763d2c49d53bf8a0d8c1bc7c2 (patch) | |
tree | 7065977b6c71f54588660cd5fd71f801483a0a0b /gcc/fortran | |
parent | f0050a4b2a8ac6d61eeffcac8ad484be9ed462a3 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fortran/class.c | 33 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 1 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 4 |
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 |