aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 309baf1c69e..2f5e4342afa 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
/* Only for gfc_trans_code. Shouldn't need to include this. */
#include "trans-stmt.h"
#include "gomp-constants.h"
+#include "gimplify.h"
#define MAX_LABEL_VALUE 99999
@@ -732,6 +733,7 @@ gfc_get_module_backend_decl (gfc_symbol *sym)
st = NULL;
s = NULL;
+ /* Check for a symbol with the same name. */
if (gsym)
gfc_find_symbol (sym->name, gsym->ns, 0, &s);
@@ -748,22 +750,37 @@ gfc_get_module_backend_decl (gfc_symbol *sym)
st->n.sym = sym;
sym->refs++;
}
- else if (sym->attr.flavor == FL_DERIVED)
+ else if (gfc_fl_struct (sym->attr.flavor))
{
if (s && s->attr.flavor == FL_PROCEDURE)
{
gfc_interface *intr;
gcc_assert (s->attr.generic);
for (intr = s->generic; intr; intr = intr->next)
- if (intr->sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (intr->sym->attr.flavor))
{
s = intr->sym;
break;
}
}
- if (!s->backend_decl)
- s->backend_decl = gfc_get_derived_type (s);
+ /* Normally we can assume that s is a derived-type symbol since it
+ shares a name with the derived-type sym. However if sym is a
+ STRUCTURE, it may in fact share a name with any other basic type
+ variable. If s is in fact of derived type then we can continue
+ looking for a duplicate type declaration. */
+ if (sym->attr.flavor == FL_STRUCT && s->ts.type == BT_DERIVED)
+ {
+ s = s->ts.u.derived;
+ }
+
+ if (gfc_fl_struct (s->attr.flavor) && !s->backend_decl)
+ {
+ if (s->attr.flavor == FL_UNION)
+ s->backend_decl = gfc_get_union_type (s);
+ else
+ s->backend_decl = gfc_get_derived_type (s);
+ }
gfc_copy_dt_decls_ifequal (s, sym, true);
return true;
}
@@ -2384,7 +2401,7 @@ create_function_arglist (gfc_symbol * sym)
Thus, we will use a hidden argument in that case. */
else if (f->sym->attr.optional && f->sym->attr.value
&& !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
- && f->sym->ts.type != BT_DERIVED)
+ && !gfc_bt_struct (f->sym->ts.type))
{
tree tmp;
strcpy (&name[1], f->sym->name);
@@ -3738,7 +3755,7 @@ gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
var = gfc_create_var_np (TREE_TYPE (t), NULL);
gfc_add_decl_to_function (var);
- gfc_add_modify (body, var, val);
+ gfc_add_modify (body, var, unshare_expr (val));
if (TREE_CODE (t) == SAVE_EXPR)
TREE_OPERAND (t, 0) = var;
*tp = var;
@@ -4596,7 +4613,7 @@ gfc_create_module_variable (gfc_symbol * sym)
&& sym->ts.type == BT_DERIVED)
sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
- if (sym->attr.flavor == FL_DERIVED
+ if (gfc_fl_struct (sym->attr.flavor)
&& sym->backend_decl
&& TREE_CODE (sym->backend_decl) == RECORD_TYPE)
{
@@ -4839,7 +4856,7 @@ check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
}
else switch (ts->type)
{
- case BT_DERIVED:
+ case_bt_struct:
if (expr->expr_type != EXPR_STRUCTURE)
return false;
cm = expr->ts.u.derived->components;