summaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-20 21:49:12 +0000
committerburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-20 21:49:12 +0000
commitc9c81ef3c667aaa14c498a5449ec6d134b4b66ff (patch)
tree0ac440db6513ee01deb5e5dc6142769d1e5b7b2d /gcc/fortran/resolve.c
parent12cdcb9d74f55c165366ca1b1eeec013a0ce72ef (diff)
parent891196d7325e4c55d92d5ac5cfe7161c4f36c0ce (diff)
downloadgcc-fortran-dev.tar.gz
Merge from trunk (r239915 to r240230)fortran-dev
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/fortran-dev@240290 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c76
1 files changed, 57 insertions, 19 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 39c1330c455..037c2fe74e0 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -6928,6 +6928,35 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2)
return true;
}
+static void
+cond_init (gfc_code *code, gfc_expr *e, int pointer, gfc_expr *init_e)
+{
+ gfc_code *block;
+ gfc_expr *cond;
+ gfc_code *init_st;
+ gfc_expr *e_to_init = gfc_expr_to_initialize (e);
+
+ cond = pointer
+ ? gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_ASSOCIATED,
+ "associated", code->loc, 2, gfc_copy_expr (e_to_init), NULL)
+ : gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_ALLOCATED,
+ "allocated", code->loc, 1, gfc_copy_expr (e_to_init));
+
+ init_st = gfc_get_code (EXEC_INIT_ASSIGN);
+ init_st->loc = code->loc;
+ init_st->expr1 = e_to_init;
+ init_st->expr2 = init_e;
+
+ block = gfc_get_code (EXEC_IF);
+ block->loc = code->loc;
+ block->block = gfc_get_code (EXEC_IF);
+ block->block->loc = code->loc;
+ block->block->expr1 = cond;
+ block->block->next = init_st;
+ block->next = code->next;
+
+ code->next = block;
+}
/* Resolve the expression in an ALLOCATE statement, doing the additional
checks to see whether the expression is OK or not. The expression must
@@ -7193,14 +7222,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
ts = ts.u.derived->components->ts;
if (gfc_bt_struct (ts.type) && (init_e = gfc_default_initializer (&ts)))
- {
- gfc_code *init_st = gfc_get_code (EXEC_INIT_ASSIGN);
- init_st->loc = code->loc;
- init_st->expr1 = gfc_expr_to_initialize (e);
- init_st->expr2 = init_e;
- init_st->next = code->next;
- code->next = init_st;
- }
+ cond_init (code, e, pointer, init_e);
}
else if (code->expr3->mold && code->expr3->ts.type == BT_DERIVED)
{
@@ -11488,6 +11510,27 @@ resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag)
}
+/* F2008, C402 (R401): A colon shall not be used as a type-param-value
+ except in the declaration of an entity or component that has the POINTER
+ or ALLOCATABLE attribute. */
+
+static bool
+deferred_requirements (gfc_symbol *sym)
+{
+ if (sym->ts.deferred
+ && !(sym->attr.pointer
+ || sym->attr.allocatable
+ || sym->attr.omp_udr_artificial_var))
+ {
+ gfc_error ("Entity %qs at %L has a deferred type parameter and "
+ "requires either the POINTER or ALLOCATABLE attribute",
+ sym->name, &sym->declared_at);
+ return false;
+ }
+ return true;
+}
+
+
/* Resolve symbols with flavor variable. */
static bool
@@ -11527,17 +11570,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
}
/* Constraints on deferred type parameter. */
- if (sym->ts.deferred
- && !(sym->attr.pointer
- || sym->attr.allocatable
- || sym->attr.omp_udr_artificial_var))
- {
- gfc_error ("Entity %qs at %L has a deferred type parameter and "
- "requires either the pointer or allocatable attribute",
- sym->name, &sym->declared_at);
- specification_expr = saved_specification_expr;
- return false;
- }
+ if (!deferred_requirements (sym))
+ return false;
if (sym->ts.type == BT_CHARACTER)
{
@@ -13682,6 +13716,10 @@ resolve_fl_parameter (gfc_symbol *sym)
return false;
}
+ /* Constraints on deferred type parameter. */
+ if (!deferred_requirements (sym))
+ return false;
+
/* Make sure a parameter that has been implicitly typed still
matches the implicit type, since PARAMETER statements can precede
IMPLICIT statements. */