Dear All,
In the last hour, I have added fixes for PRs 82587 and 82589. Please
review them together with 82586.
I will stop work on Gerhard's PDT bugs until this patch is committed.
Fortunately, Steve Kargl has proposed fixes for most of them :-)
Cheers
Paul
2017-10-20 Paul Thomas <[email protected]>
PR fortran/82586
* decl.c (gfc_get_pdt_instance): Remove the error message that
the parameter does not have a corresponding component since
this is now taken care of when the derived type is resolved. Go
straight to error return instead.
(gfc_match_formal_arglist): Make the PDT relevant errors
immediate so that parsing of the derived type can continue.
(gfc_match_derived_decl): Do not check the match status on
return from gfc_match_formal_arglist for the same reason.
* resolve.c (resolve_fl_derived0): Check that each type
parameter has a corresponding component.
PR fortran/82587
* resolve.c (resolve_generic_f): Check that the derived type
can be used before resolving the struture constructor.
PR fortran/82589
* symbol.c (check_conflict): Add the conflicts involving PDT
KIND and LEN attributes.
2017-10-20 Paul Thomas <[email protected]>
PR fortran/82586
* gfortran.dg/pdt_16.f03 : New test.
* gfortran.dg/pdt_4.f03 : Catch the changed messages.
* gfortran.dg/pdt_8.f03 : Ditto.
PR fortran/82587
* gfortran.dg/pdt_17.f03 : New test.
PR fortran/82589
* gfortran.dg/pdt_18.f03 : New test.
On 20 October 2017 at 18:17, Paul Richard Thomas
<[email protected]> wrote:
> Dear All,
>
> The attached patch is pretty clear with the ChangeLogs and is very
> nearly obvious.
>
> Bootstrapped and regtested on FC23/x86_64 - OK for trunk?
>
> Paul
>
> 2017-10-20 Paul Thomas <[email protected]>
>
> PR fortran/82586
> * decl.c (gfc_get_pdt_instance): Remove the error message that
> the parameter does not have a corresponding component since
> this is now taken care of when the derived type is resolved. Go
> straight to error return instead.
> (gfc_match_formal_arglist): Make the PDT relevant errors
> immediate so that parsing of the derived type can continue.
> (gfc_match_derived_decl): Do not check the match status on
> return from gfc_match_formal_arglist for the same reason.
> * resolve.c (resolve_fl_derived0): Check that each type
> parameter has a corresponding component.
>
> 2017-10-20 Paul Thomas <[email protected]>
>
> PR fortran/82586
> * gfortran.dg/pdt_16.f03 : New test.
> * gfortran.dg/pdt_4.f03 : Catch the changed messages.
> * gfortran.dg/pdt_8.f03 : Ditto.
>
>
> --
> "If you can't explain it simply, you don't understand it well enough"
> - Albert Einstein
--
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein
Index: gcc/fortran/decl.c
===================================================================
*** gcc/fortran/decl.c (revision 253847)
--- gcc/fortran/decl.c (working copy)
*************** gfc_get_pdt_instance (gfc_actual_arglist
*** 3242,3254 ****
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;
if (!name_seen)
--- 3242,3251 ----
param = type_param_name_list->sym;
c1 = gfc_find_component (pdt, param->name, false, true, NULL);
+ /* An error should already have been thrown in resolve.c
+ (resolve_fl_derived0). */
if (!pdt->attr.use_assoc && !c1)
! goto error_return;
kind_expr = NULL;
if (!name_seen)
*************** gfc_match_formal_arglist (gfc_symbol *pr
*** 5984,5990 ****
/* The name of a program unit can be in a different namespace,
so check for it explicitly. After the statement is accepted,
the name is checked for especially in gfc_get_symbol(). */
! if (gfc_new_block != NULL && sym != NULL
&& strcmp (sym->name, gfc_new_block->name) == 0)
{
gfc_error ("Name %qs at %C is the name of the procedure",
--- 5981,5987 ----
/* The name of a program unit can be in a different namespace,
so check for it explicitly. After the statement is accepted,
the name is checked for especially in gfc_get_symbol(). */
! if (gfc_new_block != NULL && sym != NULL && !typeparam
&& strcmp (sym->name, gfc_new_block->name) == 0)
{
gfc_error ("Name %qs at %C is the name of the procedure",
*************** gfc_match_formal_arglist (gfc_symbol *pr
*** 5999,6005 ****
m = gfc_match_char (',');
if (m != MATCH_YES)
{
! gfc_error ("Unexpected junk in formal argument list at %C");
goto cleanup;
}
}
--- 5996,6006 ----
m = gfc_match_char (',');
if (m != MATCH_YES)
{
! if (typeparam)
! gfc_error_now ("Expected parameter list in type declaration "
! "at %C");
! else
! gfc_error ("Unexpected junk in formal argument list at %C");
goto cleanup;
}
}
*************** ok:
*** 6016,6023 ****
for (q = p->next; q; q = q->next)
if (p->sym == q->sym)
{
! gfc_error ("Duplicate symbol %qs in formal argument list "
! "at %C", p->sym->name);
m = MATCH_ERROR;
goto cleanup;
--- 6017,6028 ----
for (q = p->next; q; q = q->next)
if (p->sym == q->sym)
{
! if (typeparam)
! gfc_error_now ("Duplicate name %qs in parameter "
! "list at %C", p->sym->name);
! else
! gfc_error ("Duplicate symbol %qs in formal argument "
! "list at %C", p->sym->name);
m = MATCH_ERROR;
goto cleanup;
*************** gfc_match_derived_decl (void)
*** 9814,9822 ****
if (parameterized_type)
{
! m = gfc_match_formal_arglist (sym, 0, 0, true);
! if (m != MATCH_YES)
! return m;
m = gfc_match_eos ();
if (m != MATCH_YES)
return m;
--- 9819,9827 ----
if (parameterized_type)
{
! /* Ignore error or mismatches to avoid the component declarations
! causing problems later. */
! gfc_match_formal_arglist (sym, 0, 0, true);
m = gfc_match_eos ();
if (m != MATCH_YES)
return m;
Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c (revision 253847)
--- gcc/fortran/resolve.c (working copy)
*************** generic:
*** 2694,2699 ****
--- 2694,2701 ----
if (!gfc_convert_to_structure_constructor (expr, intr->sym, NULL,
NULL, false))
return false;
+ if (!gfc_use_derived (expr->ts.u.derived))
+ return false;
return resolve_structure_cons (expr, 0);
}
*************** resolve_fl_derived0 (gfc_symbol *sym)
*** 13844,13849 ****
--- 13846,13852 ----
{
gfc_symbol* super_type;
gfc_component *c;
+ gfc_formal_arglist *f;
bool success;
if (sym->attr.unlimited_polymorphic)
*************** resolve_fl_derived0 (gfc_symbol *sym)
*** 13896,13901 ****
--- 13899,13920 ----
&& !ensure_not_abstract (sym, super_type))
return false;
+ /* Check that there is a component for every PDT parameter. */
+ if (sym->attr.pdt_template)
+ {
+ for (f = sym->formal; f; f = f->next)
+ {
+ c = gfc_find_component (sym, f->sym->name, true, true, NULL);
+ if (c == NULL)
+ {
+ gfc_error ("Parameterized type %qs does not have a component "
+ "corresponding to parameter %qs at %L", sym->name,
+ f->sym->name, &sym->declared_at);
+ break;
+ }
+ }
+ }
+
/* Add derived type to the derived type list. */
add_dt_to_dt_list (sym);
Index: gcc/fortran/symbol.c
===================================================================
*** gcc/fortran/symbol.c (revision 253847)
--- gcc/fortran/symbol.c (working copy)
*************** check_conflict (symbol_attribute *attr,
*** 382,388 ****
*is_bind_c = "BIND(C)", *procedure = "PROCEDURE",
*proc_pointer = "PROCEDURE POINTER", *abstract = "ABSTRACT",
*asynchronous = "ASYNCHRONOUS", *codimension = "CODIMENSION",
! *contiguous = "CONTIGUOUS", *generic = "GENERIC", *automatic =
"AUTOMATIC";
static const char *threadprivate = "THREADPRIVATE";
static const char *omp_declare_target = "OMP DECLARE TARGET";
static const char *omp_declare_target_link = "OMP DECLARE TARGET LINK";
--- 382,389 ----
*is_bind_c = "BIND(C)", *procedure = "PROCEDURE",
*proc_pointer = "PROCEDURE POINTER", *abstract = "ABSTRACT",
*asynchronous = "ASYNCHRONOUS", *codimension = "CODIMENSION",
! *contiguous = "CONTIGUOUS", *generic = "GENERIC", *automatic =
"AUTOMATIC",
! *pdt_len = "LEN", *pdt_kind = "KIND";
static const char *threadprivate = "THREADPRIVATE";
static const char *omp_declare_target = "OMP DECLARE TARGET";
static const char *omp_declare_target_link = "OMP DECLARE TARGET LINK";
*************** check_conflict (symbol_attribute *attr,
*** 663,668 ****
--- 664,686 ----
conf (entry, oacc_declare_deviceptr)
conf (entry, oacc_declare_device_resident)
+ conf (pdt_kind, allocatable)
+ conf (pdt_kind, pointer)
+ conf (pdt_kind, dimension)
+ conf (pdt_kind, codimension)
+
+ conf (pdt_len, allocatable)
+ conf (pdt_len, pointer)
+ conf (pdt_len, dimension)
+ conf (pdt_len, codimension)
+
+ if (attr->access == ACCESS_PRIVATE)
+ {
+ a1 = privat;
+ conf2 (pdt_kind);
+ conf2 (pdt_len);
+ }
+
a1 = gfc_code2string (flavors, attr->flavor);
if (attr->in_namelist
Index: gcc/testsuite/gfortran.dg/pdt_16.f03
===================================================================
*** gcc/testsuite/gfortran.dg/pdt_16.f03 (nonexistent)
--- gcc/testsuite/gfortran.dg/pdt_16.f03 (working copy)
***************
*** 0 ****
--- 1,21 ----
+ ! { dg-do compile }
+ !
+ ! Test the fix for all three errors in PR82586
+ !
+ ! Contributed by G Steinmetz <[email protected]>
+ !
+ module m
+ type t(a) ! { dg-error "does not have a component" }
+ end type
+ end
+
+ program p
+ type t(a ! { dg-error "Expected parameter list" }
+ integer, kind :: a
+ real(a) :: x
+ end type
+ type u(a, a) ! { dg-error "Duplicate name" }
+ integer, kind :: a ! { dg-error "already declared" }
+ integer, len :: a ! { dg-error "already declared" }
+ end type
+ end
Index: gcc/testsuite/gfortran.dg/pdt_17.f03
===================================================================
*** gcc/testsuite/gfortran.dg/pdt_17.f03 (nonexistent)
--- gcc/testsuite/gfortran.dg/pdt_17.f03 (working copy)
***************
*** 0 ****
--- 1,11 ----
+ ! { dg-do compile }
+ !
+ ! Test the fix for PR82587
+ !
+ ! Contributed by G Steinmetz <[email protected]>
+ !
+ program p
+ type t(a) ! { dg-error "does not have a component" }
+ integer(kind=t()) :: x ! { dg-error "used before it is defined" }
+ end type
+ end
Index: gcc/testsuite/gfortran.dg/pdt_18.f03
===================================================================
*** gcc/testsuite/gfortran.dg/pdt_18.f03 (nonexistent)
--- gcc/testsuite/gfortran.dg/pdt_18.f03 (working copy)
***************
*** 0 ****
--- 1,19 ----
+ ! { dg-do compile }
+ !
+ ! Test the fix for PR82589
+ !
+ ! Contributed by G Steinmetz <[email protected]>
+ !
+ module m
+ type t(a)
+ integer, KIND, private :: a ! { dg-error "attribute conflicts
with" }
+ integer, KIND, allocatable :: a ! { dg-error "attribute conflicts
with" }
+ integer, KIND, POINTER :: a ! { dg-error "attribute conflicts
with" }
+ integer, KIND, dimension(2) :: a ! { dg-error "attribute conflicts
with" }
+ integer, len, private :: a ! { dg-error "attribute conflicts
with" }
+ integer, len, allocatable :: a ! { dg-error "attribute conflicts
with" }
+ integer, len, POINTER :: a ! { dg-error "attribute conflicts
with" }
+ integer, len, dimension(2) :: a ! { dg-error "attribute conflicts
with" }
+ integer, kind :: a
+ end type
+ end
Index: gcc/testsuite/gfortran.dg/pdt_4.f03
===================================================================
*** gcc/testsuite/gfortran.dg/pdt_4.f03 (revision 253847)
--- gcc/testsuite/gfortran.dg/pdt_4.f03 (working copy)
*************** end module
*** 26,32 ****
integer, kind :: bad_kind ! { dg-error "not allowed outside a TYPE
definition" }
integer, len :: bad_len ! { dg-error "not allowed outside a TYPE
definition" }
! type :: bad_pdt (a,b, c, d)
real, kind :: a ! { dg-error "must be INTEGER" }
INTEGER(8), kind :: b ! { dg-error "be default integer kind" }
real, LEN :: c ! { dg-error "must be INTEGER" }
--- 26,32 ----
integer, kind :: bad_kind ! { dg-error "not allowed outside a TYPE
definition" }
integer, len :: bad_len ! { dg-error "not allowed outside a TYPE
definition" }
! type :: bad_pdt (a,b, c, d) ! { dg-error "does not have a component" }
real, kind :: a ! { dg-error "must be INTEGER" }
INTEGER(8), kind :: b ! { dg-error "be default integer kind" }
real, LEN :: c ! { dg-error "must be INTEGER" }
Index: gcc/testsuite/gfortran.dg/pdt_8.f03
===================================================================
*** gcc/testsuite/gfortran.dg/pdt_8.f03 (revision 253847)
--- gcc/testsuite/gfortran.dg/pdt_8.f03 (working copy)
*************** type :: t(i,a,x) ! { dg-error "d
*** 15,23 ****
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
--- 15,24 ----
real, kind :: x ! { dg-error "must be INTEGER" }
end type
! type :: t1(k,y) ! { dg-error "does not have a component" }
integer, kind :: k
end type
! ! This is a knock-on from the previous error
! type(t1(4,4)) :: z ! { dg-error "Invalid character in name" }
end