Commit 18a4e7e3 by Paul Thomas

re PR fortran/82173 ([meta-bug] Parameterized derived type errors)

2017-09-12  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/82173
	PR fortran/82168
	* decl.c (variable_decl): Check pdt template components for
	appearance of KIND/LEN components in the type parameter name
	list, that components corresponding to type parameters have
	either KIND or LEN attributes and that KIND or LEN components
	are scalar. Copy the initializer to the parameter value.
	(gfc_get_pdt_instance): Add a label 'error_return' and follow
	it with repeated code, while replacing this code with a jump.
	Check if a parameter appears as a component in the template.
	Make sure that the parameter expressions are integer. Validate
	KIND expressions.
	(gfc_match_decl_type_spec): Search for pdt_types in the parent
	namespace since they are instantiated in the template ns.
	* expr.c (gfc_extract_int): Use a KIND parameter if it
	appears as a component expression.
	(gfc_check_init_expr): Allow expressions with the pdt_kind
	attribute.
	*primary.c (gfc_match_actual_arglist): Make sure that the first
	keyword argument is recognised when 'pdt' is set.


2017-09-12  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/82173
	* gfortran.dg/pdt_4.f03 : Remove the 'is being used before it
	is defined' error.
	* gfortran.dg/pdt_6.f03 : New test.
	* gfortran.dg/pdt_7.f03 : New test.
	* gfortran.dg/pdt_8.f03 : New test.

	PR fortran/82168
	* gfortran.dg/pdt_9.f03 : New test.

From-SVN: r252039
parent 29788f90
2017-09-12 Paul Thomas <pault@gcc.gnu.org>
PR fortran/82173
PR fortran/82168
* decl.c (variable_decl): Check pdt template components for
appearance of KIND/LEN components in the type parameter name
list, that components corresponding to type parameters have
either KIND or LEN attributes and that KIND or LEN components
are scalar. Copy the initializer to the parameter value.
(gfc_get_pdt_instance): Add a label 'error_return' and follow
it with repeated code, while replacing this code with a jump.
Check if a parameter appears as a component in the template.
Make sure that the parameter expressions are integer. Validate
KIND expressions.
(gfc_match_decl_type_spec): Search for pdt_types in the parent
namespace since they are instantiated in the template ns.
* expr.c (gfc_extract_int): Use a KIND parameter if it
appears as a component expression.
(gfc_check_init_expr): Allow expressions with the pdt_kind
attribute.
*primary.c (gfc_match_actual_arglist): Make sure that the first
keyword argument is recognised when 'pdt' is set.
2017-09-10 Paul Thomas <pault@gcc.gnu.org> 2017-09-10 Paul Thomas <pault@gcc.gnu.org>
PR fortran/34640 PR fortran/34640
......
...@@ -2537,6 +2537,39 @@ variable_decl (int elem) ...@@ -2537,6 +2537,39 @@ variable_decl (int elem)
goto cleanup; goto cleanup;
} }
if (gfc_current_state () == COMP_DERIVED
&& gfc_current_block ()->attr.pdt_template)
{
gfc_symbol *param;
gfc_find_symbol (name, gfc_current_block ()->f2k_derived,
0, &param);
if (!param && (current_attr.pdt_kind || current_attr.pdt_len))
{
gfc_error ("The component with KIND or LEN attribute at %C does not "
"not appear in the type parameter list at %L",
&gfc_current_block ()->declared_at);
m = MATCH_ERROR;
goto cleanup;
}
else if (param && !(current_attr.pdt_kind || current_attr.pdt_len))
{
gfc_error ("The component at %C that appears in the type parameter "
"list at %L has neither the KIND nor LEN attribute",
&gfc_current_block ()->declared_at);
m = MATCH_ERROR;
goto cleanup;
}
else if (as && (current_attr.pdt_kind || current_attr.pdt_len))
{
gfc_error ("The component at %C which is a type parameter must be "
"a scalar");
m = MATCH_ERROR;
goto cleanup;
}
else if (param && initializer)
param->value = gfc_copy_expr (initializer);
}
/* Add the initializer. Note that it is fine if initializer is /* Add the initializer. Note that it is fine if initializer is
NULL here, because we sometimes also need to check if a NULL here, because we sometimes also need to check if a
declaration *must* have an initialization expression. */ declaration *must* have an initialization expression. */
...@@ -3193,8 +3226,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3193,8 +3226,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
{ {
gfc_error ("The type parameter spec list at %C cannot contain " gfc_error ("The type parameter spec list at %C cannot contain "
"both ASSUMED and DEFERRED parameters"); "both ASSUMED and DEFERRED parameters");
gfc_free_actual_arglist (type_param_spec_list); goto error_return;
return MATCH_ERROR;
} }
} }
...@@ -3202,10 +3234,27 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3202,10 +3234,27 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
name_seen = true; name_seen = true;
param = type_param_name_list->sym; param = type_param_name_list->sym;
c1 = gfc_find_component (pdt, param->name, false, true, NULL);
if (!pdt->attr.use_assoc && !c1)
{
gfc_error ("The type parameter name list at %L contains a parameter "
"'%qs' , which is not declared as a component of the type",
&pdt->declared_at, param->name);
goto error_return;
}
kind_expr = NULL; kind_expr = NULL;
if (!name_seen) if (!name_seen)
{ {
if (actual_param && actual_param->spec_type == SPEC_EXPLICIT) if (!actual_param && !(c1 && c1->initializer))
{
gfc_error ("The type parameter spec list at %C does not contain "
"enough parameter expressions");
goto error_return;
}
else if (!actual_param && c1 && c1->initializer)
kind_expr = gfc_copy_expr (c1->initializer);
else if (actual_param && actual_param->spec_type == SPEC_EXPLICIT)
kind_expr = gfc_copy_expr (actual_param->expr); kind_expr = gfc_copy_expr (actual_param->expr);
} }
else else
...@@ -3225,7 +3274,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3225,7 +3274,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
{ {
gfc_error ("The derived parameter '%qs' at %C does not " gfc_error ("The derived parameter '%qs' at %C does not "
"have a default value", param->name); "have a default value", param->name);
return MATCH_ERROR; goto error_return;
} }
} }
} }
...@@ -3247,6 +3296,17 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3247,6 +3296,17 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
if (kind_expr) if (kind_expr)
{ {
/* Variable expressions seem to default to BT_PROCEDURE.
TODO find out why this is and fix it. */
if (kind_expr->ts.type != BT_INTEGER
&& kind_expr->ts.type != BT_PROCEDURE)
{
gfc_error ("The parameter expression at %C must be of "
"INTEGER type and not %s type",
gfc_basic_typename (kind_expr->ts.type));
goto error_return;
}
tail->expr = gfc_copy_expr (kind_expr); tail->expr = gfc_copy_expr (kind_expr);
/* Try simplification even for LEN expressions. */ /* Try simplification even for LEN expressions. */
gfc_simplify_expr (tail->expr, 1); gfc_simplify_expr (tail->expr, 1);
...@@ -3257,7 +3317,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3257,7 +3317,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
if (!param->attr.pdt_kind) if (!param->attr.pdt_kind)
{ {
if (!name_seen) if (!name_seen && actual_param)
actual_param = actual_param->next; actual_param = actual_param->next;
if (kind_expr) if (kind_expr)
{ {
...@@ -3273,16 +3333,14 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3273,16 +3333,14 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
{ {
gfc_error ("The KIND parameter '%qs' at %C cannot either be " gfc_error ("The KIND parameter '%qs' at %C cannot either be "
"ASSUMED or DEFERRED", param->name); "ASSUMED or DEFERRED", param->name);
gfc_free_actual_arglist (type_param_spec_list); goto error_return;
return MATCH_ERROR;
} }
if (!kind_expr || !gfc_is_constant_expr (kind_expr)) if (!kind_expr || !gfc_is_constant_expr (kind_expr))
{ {
gfc_error ("The value for the KIND parameter '%qs' at %C does not " gfc_error ("The value for the KIND parameter '%qs' at %C does not "
"reduce to a constant expression", param->name); "reduce to a constant expression", param->name);
gfc_free_actual_arglist (type_param_spec_list); goto error_return;
return MATCH_ERROR;
} }
gfc_extract_int (kind_expr, &kind_value); gfc_extract_int (kind_expr, &kind_value);
...@@ -3293,12 +3351,19 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3293,12 +3351,19 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
gfc_free_expr (kind_expr); gfc_free_expr (kind_expr);
} }
if (!name_seen && actual_param)
{
gfc_error ("The type parameter spec list at %C contains too many "
"parameter expressions");
goto error_return;
}
/* Now we search for the PDT instance 'name'. If it doesn't exist, we /* Now we search for the PDT instance 'name'. If it doesn't exist, we
build it, using 'pdt' as a template. */ build it, using 'pdt' as a template. */
if (gfc_get_symbol (name, pdt->ns, &instance)) if (gfc_get_symbol (name, pdt->ns, &instance))
{ {
gfc_error ("Parameterized derived type at %C is ambiguous"); gfc_error ("Parameterized derived type at %C is ambiguous");
return MATCH_ERROR; goto error_return;
} }
m = MATCH_YES; m = MATCH_YES;
...@@ -3370,7 +3435,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3370,7 +3435,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
gfc_error ("Maximum extension level reached with type %qs at %L", gfc_error ("Maximum extension level reached with type %qs at %L",
c2->ts.u.derived->name, c2->ts.u.derived->name,
&c2->ts.u.derived->declared_at); &c2->ts.u.derived->declared_at);
return MATCH_ERROR; goto error_return;
} }
instance->attr.extension = c2->ts.u.derived->attr.extension + 1; instance->attr.extension = c2->ts.u.derived->attr.extension + 1;
...@@ -3390,6 +3455,12 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3390,6 +3455,12 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
gfc_insert_kind_parameter_exprs (e); gfc_insert_kind_parameter_exprs (e);
gfc_extract_int (e, &c2->ts.kind); gfc_extract_int (e, &c2->ts.kind);
gfc_free_expr (e); gfc_free_expr (e);
if (gfc_validate_kind (c2->ts.type, c2->ts.kind, true) < 0)
{
gfc_error ("Kind %d not supported for type %s at %C",
c2->ts.kind, gfc_basic_typename (c2->ts.type));
goto error_return;
}
} }
/* Similarly, set the string length if parameterized. */ /* Similarly, set the string length if parameterized. */
...@@ -3499,6 +3570,10 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, ...@@ -3499,6 +3570,10 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
*ext_param_list = type_param_spec_list; *ext_param_list = type_param_spec_list;
*sym = instance; *sym = instance;
return m; return m;
error_return:
gfc_free_actual_arglist (type_param_spec_list);
return MATCH_ERROR;
} }
...@@ -3829,6 +3904,19 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) ...@@ -3829,6 +3904,19 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
} }
if (sym->generic && !dt_sym) if (sym->generic && !dt_sym)
dt_sym = gfc_find_dt_in_generic (sym); dt_sym = gfc_find_dt_in_generic (sym);
/* Host associated PDTs can get confused with their constructors
because they ar instantiated in the template's namespace. */
if (!dt_sym)
{
if (gfc_find_symbol (dt_name, NULL, 1, &dt_sym))
{
gfc_error ("Type name %qs at %C is ambiguous", name);
return MATCH_ERROR;
}
if (dt_sym && !dt_sym->attr.pdt_type)
dt_sym = NULL;
}
} }
else if (ts->kind == -1) else if (ts->kind == -1)
{ {
...@@ -3861,14 +3949,14 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) ...@@ -3861,14 +3949,14 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
if (sym && sym->attr.flavor == FL_DERIVED if (sym && sym->attr.flavor == FL_DERIVED
&& sym->attr.pdt_template && sym->attr.pdt_template
&& gfc_current_state () != COMP_DERIVED) && gfc_current_state () != COMP_DERIVED)
{ {
m = gfc_get_pdt_instance (decl_type_param_list, &sym, NULL); m = gfc_get_pdt_instance (decl_type_param_list, &sym, NULL);
if (m != MATCH_YES) if (m != MATCH_YES)
return m; return m;
gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type); gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
ts->u.derived = sym; ts->u.derived = sym;
strcpy (name, gfc_dt_lower_string (sym->name)); strcpy (name, gfc_dt_lower_string (sym->name));
} }
gfc_save_symbol_data (sym); gfc_save_symbol_data (sym);
gfc_set_sym_referenced (sym); gfc_set_sym_referenced (sym);
......
...@@ -624,6 +624,20 @@ gfc_replace_expr (gfc_expr *dest, gfc_expr *src) ...@@ -624,6 +624,20 @@ gfc_replace_expr (gfc_expr *dest, gfc_expr *src)
bool bool
gfc_extract_int (gfc_expr *expr, int *result, int report_error) gfc_extract_int (gfc_expr *expr, int *result, int report_error)
{ {
gfc_ref *ref;
/* A KIND component is a parameter too. The expression for it
is stored in the initializer and should be consistent with
the tests below. */
if (gfc_expr_attr(expr).pdt_kind)
{
for (ref = expr->ref; ref; ref = ref->next)
{
if (ref->u.c.component->attr.pdt_kind)
expr = ref->u.c.component->initializer;
}
}
if (expr->expr_type != EXPR_CONSTANT) if (expr->expr_type != EXPR_CONSTANT)
{ {
if (report_error > 0) if (report_error > 0)
...@@ -2548,7 +2562,7 @@ gfc_check_init_expr (gfc_expr *e) ...@@ -2548,7 +2562,7 @@ gfc_check_init_expr (gfc_expr *e)
t = true; t = true;
/* This occurs when parsing pdt templates. */ /* This occurs when parsing pdt templates. */
if (e->symtree->n.sym->attr.pdt_kind) if (gfc_expr_attr (e).pdt_kind)
break; break;
if (gfc_check_iter_variable (e)) if (gfc_check_iter_variable (e))
......
...@@ -1796,11 +1796,6 @@ gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist **argp, bool pdt) ...@@ -1796,11 +1796,6 @@ gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist **argp, bool pdt)
if (sub_flag && !pdt && gfc_match_char ('*') == MATCH_YES) if (sub_flag && !pdt && gfc_match_char ('*') == MATCH_YES)
{ {
if (pdt)
{
tail->spec_type = SPEC_ASSUMED;
goto next;
}
m = gfc_match_st_label (&label); m = gfc_match_st_label (&label);
if (m == MATCH_NO) if (m == MATCH_NO)
gfc_error ("Expected alternate return label at %C"); gfc_error ("Expected alternate return label at %C");
...@@ -1829,6 +1824,15 @@ gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist **argp, bool pdt) ...@@ -1829,6 +1824,15 @@ gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist **argp, bool pdt)
} }
else else
tail->spec_type = SPEC_EXPLICIT; tail->spec_type = SPEC_EXPLICIT;
m = match_keyword_arg (tail, head, pdt);
if (m == MATCH_YES)
{
seen_keyword = 1;
goto next;
}
if (m == MATCH_ERROR)
goto cleanup;
} }
/* After the first keyword argument is seen, the following /* After the first keyword argument is seen, the following
......
...@@ -308,7 +308,7 @@ gfc_set_default_type (gfc_symbol *sym, int error_flag, gfc_namespace *ns) ...@@ -308,7 +308,7 @@ gfc_set_default_type (gfc_symbol *sym, int error_flag, gfc_namespace *ns)
sym->ts.f90_type = sym->ts.type; sym->ts.f90_type = sym->ts.type;
} }
} }
return true; return true;
} }
...@@ -464,7 +464,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where) ...@@ -464,7 +464,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
case FL_NAMELIST: case FL_NAMELIST:
gfc_error ("Namelist group name at %L cannot have the " gfc_error ("Namelist group name at %L cannot have the "
"SAVE attribute", where); "SAVE attribute", where);
return false; return false;
case FL_PROCEDURE: case FL_PROCEDURE:
/* Conflicts between SAVE and PROCEDURE will be checked at /* Conflicts between SAVE and PROCEDURE will be checked at
resolution stage, see "resolve_fl_procedure". */ resolution stage, see "resolve_fl_procedure". */
...@@ -513,7 +513,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where) ...@@ -513,7 +513,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
if ((attr->if_source == IFSRC_DECL && !attr->procedure) || attr->contained) if ((attr->if_source == IFSRC_DECL && !attr->procedure) || attr->contained)
conf (external, subroutine); conf (external, subroutine);
if (attr->proc_pointer && !gfc_notify_std (GFC_STD_F2003, if (attr->proc_pointer && !gfc_notify_std (GFC_STD_F2003,
"Procedure pointer at %C")) "Procedure pointer at %C"))
return false; return false;
...@@ -1197,8 +1197,8 @@ gfc_add_protected (symbol_attribute *attr, const char *name, locus *where) ...@@ -1197,8 +1197,8 @@ gfc_add_protected (symbol_attribute *attr, const char *name, locus *where)
if (attr->is_protected) if (attr->is_protected)
{ {
if (!gfc_notify_std (GFC_STD_LEGACY, if (!gfc_notify_std (GFC_STD_LEGACY,
"Duplicate PROTECTED attribute specified at %L", "Duplicate PROTECTED attribute specified at %L",
where)) where))
return false; return false;
} }
...@@ -1241,8 +1241,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name, ...@@ -1241,8 +1241,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name,
if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT) if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT)
{ {
if (!gfc_notify_std (GFC_STD_LEGACY, if (!gfc_notify_std (GFC_STD_LEGACY,
"Duplicate SAVE attribute specified at %L", "Duplicate SAVE attribute specified at %L",
where)) where))
return false; return false;
} }
...@@ -1261,8 +1261,8 @@ gfc_add_value (symbol_attribute *attr, const char *name, locus *where) ...@@ -1261,8 +1261,8 @@ gfc_add_value (symbol_attribute *attr, const char *name, locus *where)
if (attr->value) if (attr->value)
{ {
if (!gfc_notify_std (GFC_STD_LEGACY, if (!gfc_notify_std (GFC_STD_LEGACY,
"Duplicate VALUE attribute specified at %L", "Duplicate VALUE attribute specified at %L",
where)) where))
return false; return false;
} }
...@@ -1280,8 +1280,8 @@ gfc_add_volatile (symbol_attribute *attr, const char *name, locus *where) ...@@ -1280,8 +1280,8 @@ gfc_add_volatile (symbol_attribute *attr, const char *name, locus *where)
given a VOLATILE attribute - unless it is a coarray (F2008, C560). */ given a VOLATILE attribute - unless it is a coarray (F2008, C560). */
if (attr->volatile_ && attr->volatile_ns == gfc_current_ns) if (attr->volatile_ && attr->volatile_ns == gfc_current_ns)
if (!gfc_notify_std (GFC_STD_LEGACY, if (!gfc_notify_std (GFC_STD_LEGACY,
"Duplicate VOLATILE attribute specified at %L", "Duplicate VOLATILE attribute specified at %L",
where)) where))
return false; return false;
...@@ -1299,8 +1299,8 @@ gfc_add_asynchronous (symbol_attribute *attr, const char *name, locus *where) ...@@ -1299,8 +1299,8 @@ gfc_add_asynchronous (symbol_attribute *attr, const char *name, locus *where)
given a ASYNCHRONOUS attribute. */ given a ASYNCHRONOUS attribute. */
if (attr->asynchronous && attr->asynchronous_ns == gfc_current_ns) if (attr->asynchronous && attr->asynchronous_ns == gfc_current_ns)
if (!gfc_notify_std (GFC_STD_LEGACY, if (!gfc_notify_std (GFC_STD_LEGACY,
"Duplicate ASYNCHRONOUS attribute specified at %L", "Duplicate ASYNCHRONOUS attribute specified at %L",
where)) where))
return false; return false;
...@@ -1814,10 +1814,10 @@ gfc_add_is_bind_c (symbol_attribute *attr, const char *name, locus *where, ...@@ -1814,10 +1814,10 @@ gfc_add_is_bind_c (symbol_attribute *attr, const char *name, locus *where,
gfc_error_now ("Duplicate BIND attribute specified at %L", where); gfc_error_now ("Duplicate BIND attribute specified at %L", where);
else else
attr->is_bind_c = 1; attr->is_bind_c = 1;
if (where == NULL) if (where == NULL)
where = &gfc_current_locus; where = &gfc_current_locus;
if (!gfc_notify_std (GFC_STD_F2003, "BIND(C) at %L", where)) if (!gfc_notify_std (GFC_STD_F2003, "BIND(C) at %L", where))
return false; return false;
...@@ -1970,7 +1970,7 @@ bool ...@@ -1970,7 +1970,7 @@ bool
gfc_copy_attr (symbol_attribute *dest, symbol_attribute *src, locus *where) gfc_copy_attr (symbol_attribute *dest, symbol_attribute *src, locus *where)
{ {
int is_proc_lang_bind_spec; int is_proc_lang_bind_spec;
/* In line with the other attributes, we only add bits but do not remove /* In line with the other attributes, we only add bits but do not remove
them; cf. also PR 41034. */ them; cf. also PR 41034. */
dest->ext_attr |= src->ext_attr; dest->ext_attr |= src->ext_attr;
...@@ -2081,7 +2081,7 @@ gfc_copy_attr (symbol_attribute *dest, symbol_attribute *src, locus *where) ...@@ -2081,7 +2081,7 @@ gfc_copy_attr (symbol_attribute *dest, symbol_attribute *src, locus *where)
dest->is_c_interop = 1; dest->is_c_interop = 1;
if (src->is_iso_c) if (src->is_iso_c)
dest->is_iso_c = 1; dest->is_iso_c = 1;
if (src->external && !gfc_add_external (dest, where)) if (src->external && !gfc_add_external (dest, where))
goto fail; goto fail;
if (src->intrinsic && !gfc_add_intrinsic (dest, where)) if (src->intrinsic && !gfc_add_intrinsic (dest, where))
...@@ -2341,7 +2341,7 @@ find_union_component (gfc_symbol *un, const char *name, ...@@ -2341,7 +2341,7 @@ find_union_component (gfc_symbol *un, const char *name,
not found or the components are private. If noaccess is set, no access not found or the components are private. If noaccess is set, no access
checks are done. If silent is set, an error will not be generated if checks are done. If silent is set, an error will not be generated if
the component cannot be found or accessed. the component cannot be found or accessed.
If ref is not NULL, *ref is set to represent the chain of components If ref is not NULL, *ref is set to represent the chain of components
required to get to the ultimate component. required to get to the ultimate component.
...@@ -2530,7 +2530,7 @@ free_st_labels (gfc_st_label *label) ...@@ -2530,7 +2530,7 @@ free_st_labels (gfc_st_label *label)
free_st_labels (label->left); free_st_labels (label->left);
free_st_labels (label->right); free_st_labels (label->right);
if (label->format != NULL) if (label->format != NULL)
gfc_free_expr (label->format); gfc_free_expr (label->format);
free (label); free (label);
...@@ -3022,7 +3022,7 @@ gfc_new_symbol (const char *name, gfc_namespace *ns) ...@@ -3022,7 +3022,7 @@ gfc_new_symbol (const char *name, gfc_namespace *ns)
p->f2k_derived = NULL; p->f2k_derived = NULL;
p->assoc = NULL; p->assoc = NULL;
p->fn_result_spec = 0; p->fn_result_spec = 0;
return p; return p;
} }
...@@ -3379,7 +3379,7 @@ find_common_symtree (gfc_symtree *st, gfc_common_head *head) ...@@ -3379,7 +3379,7 @@ find_common_symtree (gfc_symtree *st, gfc_common_head *head)
return st; return st;
result = find_common_symtree (st->left, head); result = find_common_symtree (st->left, head);
if (!result) if (!result)
result = find_common_symtree (st->right, head); result = find_common_symtree (st->right, head);
return result; return result;
...@@ -3403,7 +3403,7 @@ gfc_new_undo_checkpoint (gfc_undo_change_set &chg_syms) ...@@ -3403,7 +3403,7 @@ gfc_new_undo_checkpoint (gfc_undo_change_set &chg_syms)
/* Restore previous state of symbol. Just copy simple stuff. */ /* Restore previous state of symbol. Just copy simple stuff. */
static void static void
restore_old_symbol (gfc_symbol *p) restore_old_symbol (gfc_symbol *p)
{ {
...@@ -3645,10 +3645,10 @@ free_old_symbol (gfc_symbol *sym) ...@@ -3645,10 +3645,10 @@ free_old_symbol (gfc_symbol *sym)
if (sym->old_symbol == NULL) if (sym->old_symbol == NULL)
return; return;
if (sym->old_symbol->as != sym->as) if (sym->old_symbol->as != sym->as)
gfc_free_array_spec (sym->old_symbol->as); gfc_free_array_spec (sym->old_symbol->as);
if (sym->old_symbol->value != sym->value) if (sym->old_symbol->value != sym->value)
gfc_free_expr (sym->old_symbol->value); gfc_free_expr (sym->old_symbol->value);
if (sym->old_symbol->formal != sym->formal) if (sym->old_symbol->formal != sym->formal)
...@@ -3741,7 +3741,7 @@ free_common_tree (gfc_symtree * common_tree) ...@@ -3741,7 +3741,7 @@ free_common_tree (gfc_symtree * common_tree)
free_common_tree (common_tree->right); free_common_tree (common_tree->right);
free (common_tree); free (common_tree);
} }
/* Recursive function that deletes an entire tree and all the common /* Recursive function that deletes an entire tree and all the common
...@@ -3890,7 +3890,7 @@ gfc_new_charlen (gfc_namespace *ns, gfc_charlen *old_cl) ...@@ -3890,7 +3890,7 @@ gfc_new_charlen (gfc_namespace *ns, gfc_charlen *old_cl)
} }
/* Free the charlen list from cl to end (end is not freed). /* Free the charlen list from cl to end (end is not freed).
Free the whole list if end is NULL. */ Free the whole list if end is NULL. */
void void
...@@ -4047,7 +4047,7 @@ do_traverse_symtree (gfc_symtree *st, void (*st_func) (gfc_symtree *), ...@@ -4047,7 +4047,7 @@ do_traverse_symtree (gfc_symtree *st, void (*st_func) (gfc_symtree *),
gcc_assert ((st_func && !sym_func) || (!st_func && sym_func)); gcc_assert ((st_func && !sym_func) || (!st_func && sym_func));
nodes = count_st_nodes (st); nodes = count_st_nodes (st);
st_vec = XALLOCAVEC (gfc_symtree *, nodes); st_vec = XALLOCAVEC (gfc_symtree *, nodes);
node_cntr = 0; node_cntr = 0;
fill_st_vector (st, st_vec, node_cntr); fill_st_vector (st, st_vec, node_cntr);
if (sym_func) if (sym_func)
...@@ -4265,7 +4265,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4265,7 +4265,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
gfc_component *curr_comp = NULL; gfc_component *curr_comp = NULL;
bool is_c_interop = false; bool is_c_interop = false;
bool retval = true; bool retval = true;
if (derived_sym == NULL) if (derived_sym == NULL)
gfc_internal_error ("verify_bind_c_derived_type(): Given symbol is " gfc_internal_error ("verify_bind_c_derived_type(): Given symbol is "
"unexpectedly NULL"); "unexpectedly NULL");
...@@ -4274,7 +4274,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4274,7 +4274,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
so we don't repeat warnings/errors. */ so we don't repeat warnings/errors. */
if (derived_sym->ts.is_c_interop) if (derived_sym->ts.is_c_interop)
return true; return true;
/* The derived type must have the BIND attribute to be interoperable /* The derived type must have the BIND attribute to be interoperable
J3/04-007, Section 15.2.3. */ J3/04-007, Section 15.2.3. */
if (derived_sym->attr.is_bind_c != 1) if (derived_sym->attr.is_bind_c != 1)
...@@ -4285,7 +4285,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4285,7 +4285,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
&(derived_sym->declared_at)); &(derived_sym->declared_at));
retval = false; retval = false;
} }
curr_comp = derived_sym->components; curr_comp = derived_sym->components;
/* Fortran 2003 allows an empty derived type. C99 appears to disallow an /* Fortran 2003 allows an empty derived type. C99 appears to disallow an
...@@ -4310,12 +4310,12 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4310,12 +4310,12 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
/* Initialize the derived type as being C interoperable. /* Initialize the derived type as being C interoperable.
If we find an error in the components, this will be set false. */ If we find an error in the components, this will be set false. */
derived_sym->ts.is_c_interop = 1; derived_sym->ts.is_c_interop = 1;
/* Loop through the list of components to verify that the kind of /* Loop through the list of components to verify that the kind of
each is a C interoperable type. */ each is a C interoperable type. */
do do
{ {
/* The components cannot be pointers (fortran sense). /* The components cannot be pointers (fortran sense).
J3/04-007, Section 15.2.3, C1505. */ J3/04-007, Section 15.2.3, C1505. */
if (curr_comp->attr.pointer != 0) if (curr_comp->attr.pointer != 0)
{ {
...@@ -4347,10 +4347,10 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4347,10 +4347,10 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
derived_sym->name, &(derived_sym->declared_at)); derived_sym->name, &(derived_sym->declared_at));
retval = false; retval = false;
} }
/* BIND(C) derived types must have interoperable components. */ /* BIND(C) derived types must have interoperable components. */
if (curr_comp->ts.type == BT_DERIVED if (curr_comp->ts.type == BT_DERIVED
&& curr_comp->ts.u.derived->ts.is_iso_c != 1 && curr_comp->ts.u.derived->ts.is_iso_c != 1
&& curr_comp->ts.u.derived != derived_sym) && curr_comp->ts.u.derived != derived_sym)
{ {
/* This should be allowed; the draft says a derived-type can not /* This should be allowed; the draft says a derived-type can not
...@@ -4361,9 +4361,9 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4361,9 +4361,9 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
} }
else else
{ {
/* Grab the typespec for the given component and test the kind. */ /* Grab the typespec for the given component and test the kind. */
is_c_interop = gfc_verify_c_interop (&(curr_comp->ts)); is_c_interop = gfc_verify_c_interop (&(curr_comp->ts));
if (!is_c_interop) if (!is_c_interop)
{ {
/* Report warning and continue since not fatal. The /* Report warning and continue since not fatal. The
...@@ -4395,9 +4395,9 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4395,9 +4395,9 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
&(curr_comp->loc)); &(curr_comp->loc));
} }
} }
curr_comp = curr_comp->next; curr_comp = curr_comp->next;
} while (curr_comp != NULL); } while (curr_comp != NULL);
/* Make sure we don't have conflicts with the attributes. */ /* Make sure we don't have conflicts with the attributes. */
...@@ -4422,7 +4422,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) ...@@ -4422,7 +4422,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
it's interoperable. */ it's interoperable. */
if (!retval) if (!retval)
derived_sym->ts.is_c_interop = 0; derived_sym->ts.is_c_interop = 0;
return retval; return retval;
} }
...@@ -4445,7 +4445,7 @@ gen_special_c_interop_ptr (gfc_symbol *tmp_sym, gfc_symtree *dt_symtree) ...@@ -4445,7 +4445,7 @@ gen_special_c_interop_ptr (gfc_symbol *tmp_sym, gfc_symtree *dt_symtree)
tmp_sym->ts.f90_type = BT_VOID; tmp_sym->ts.f90_type = BT_VOID;
tmp_sym->attr.flavor = FL_PARAMETER; tmp_sym->attr.flavor = FL_PARAMETER;
tmp_sym->ts.u.derived = dt_symtree->n.sym; tmp_sym->ts.u.derived = dt_symtree->n.sym;
/* Set the c_address field of c_null_ptr and c_null_funptr to /* Set the c_address field of c_null_ptr and c_null_funptr to
the value of NULL. */ the value of NULL. */
tmp_sym->value = gfc_get_expr (); tmp_sym->value = gfc_get_expr ();
...@@ -4480,10 +4480,10 @@ add_formal_arg (gfc_formal_arglist **head, ...@@ -4480,10 +4480,10 @@ add_formal_arg (gfc_formal_arglist **head,
(*tail)->next = formal_arg; (*tail)->next = formal_arg;
(*tail) = formal_arg; (*tail) = formal_arg;
} }
(*tail)->sym = param_sym; (*tail)->sym = param_sym;
(*tail)->next = NULL; (*tail)->next = NULL;
return; return;
} }
...@@ -4696,7 +4696,7 @@ generate_isocbinding_symbol (const char *mod_name, iso_c_binding_symbol s, ...@@ -4696,7 +4696,7 @@ generate_isocbinding_symbol (const char *mod_name, iso_c_binding_symbol s,
switch (s) switch (s)
{ {
#define NAMED_INTCST(a,b,c,d) case a : #define NAMED_INTCST(a,b,c,d) case a :
#define NAMED_REALCST(a,b,c,d) case a : #define NAMED_REALCST(a,b,c,d) case a :
#define NAMED_CMPXCST(a,b,c,d) case a : #define NAMED_CMPXCST(a,b,c,d) case a :
#define NAMED_LOGCST(a,b,c) case a : #define NAMED_LOGCST(a,b,c) case a :
......
2017-09-12 Paul Thomas <pault@gcc.gnu.org>
PR fortran/82173
* gfortran.dg/pdt_4.f03 : Remove the 'is being used before it
is defined' error.
* gfortran.dg/pdt_6.f03 : New test.
* gfortran.dg/pdt_7.f03 : New test.
* gfortran.dg/pdt_8.f03 : New test.
PR fortran/82168
* gfortran.dg/pdt_9.f03 : New test.
2017-09-12 Jakub Jelinek <jakub@redhat.com> 2017-09-12 Jakub Jelinek <jakub@redhat.com>
PR target/82112 PR target/82112
......
...@@ -81,8 +81,8 @@ end module ...@@ -81,8 +81,8 @@ end module
end select end select
deallocate (cz) deallocate (cz)
contains contains
subroutine foo(arg) ! { dg-error "has no IMPLICIT type" } subroutine foo(arg)
type (mytype(4, *)) :: arg ! { dg-error "is being used before it is defined" } type (mytype(4, *)) :: arg ! used to have an invalid "is being used before it is defined"
end subroutine end subroutine
subroutine bar(arg) ! { dg-error "cannot have DEFERRED type parameters" } subroutine bar(arg) ! { dg-error "cannot have DEFERRED type parameters" }
type (thytype(8, :, 4) :: arg type (thytype(8, :, 4) :: arg
......
! { dg-do compile }
!
! Fixes of ICE on invalid & accepts invalid
!
! Contributed by Janus Weil <janus@gcc.gnu.org>
!
implicit none
type :: param_matrix(c,r)
integer, len :: c,r
real :: m(c,r)
end type
type real_array(k)
integer, kind :: k
real(kind=k), allocatable :: r(:)
end type
type(param_matrix(1)) :: m1 ! { dg-error "does not contain enough parameter" }
type(param_matrix(1,2)) :: m2 ! ok
type(param_matrix(1,2,3)) :: m3 ! { dg-error "contains too many parameter" }
type(param_matrix(1,2.5)) :: m4 ! { dg-error "must be of INTEGER type" }
type(real_array(4)) :: a1 ! ok
type(real_array(5)) :: a2 ! { dg-error "Kind 5 not supported for type REAL" }
end
! { dg-do run }
!
! Rejected valid
!
! ! Contributed by Janus Weil <janus@gcc.gnu.org>
!
implicit none
type :: param_matrix(k,c,r)
integer, kind :: k
integer, len :: c,r
real(kind=k) :: m(c,r)
end type
type(param_matrix(8,3,2)) :: mat
real(kind=mat%k) :: m ! Corrected error: Parameter ‘mat’ at (1) has not been declared or ...
if (kind(m) .ne. 8) call abort
end
! { dg-do compile }
!
! Fixes of "accepts invalid".
! Note that the undeclared parameter 'y' in 't1' was originally in the
! type 't'. It turned out to be convenient to defer the error until the
! type is used in the declaration of 'z'.
!
! Contributed by Janus Weil <janus@gcc.gnu.org>
!
implicit none
type :: t(i,a,x) ! { dg-error "does not|has neither" }
integer, kind :: k ! { dg-error "does not not appear in the type parameter list" }
integer :: i ! { dg-error "has neither the KIND nor LEN attribute" }
integer, kind :: a(3) ! { dg-error "must be a scalar" }
real, kind :: x ! { dg-error "must be INTEGER" }
end type
type :: t1(k,y) ! { dg-error "not declared as a component of the type" }
integer, kind :: k
end type
type(t1(4,4)) :: z
end
! { dg-do compile }
!
! Test the fix for PR82168 in which the declarations for 'a'
! and 'b' threw errors even though they are valid.
!
! Contributed by <physiker@toast2.net>
!
module mod
implicit none
integer, parameter :: dp = kind (0.0d0)
type, public :: v(z, k)
integer, len :: z
integer, kind :: k = kind(0.0)
real(kind = k) :: e(z)
end type v
end module mod
program bug
use mod
implicit none
type (v(2)) :: a ! Missing parameter replaced by initializer.
type (v(z=:, k=dp)), allocatable :: b ! Keyword was not working for '*' or ':'
end program bug
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment