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  <pa...@gcc.gnu.org>

    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  <pa...@gcc.gnu.org>

    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
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)
*************** resolve_fl_derived0 (gfc_symbol *sym)
*** 13844,13849 ****
--- 13844,13850 ----
  {
    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 ****
--- 13897,13918 ----
        && !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/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  <gs...@t-online.de>
+ !
+ 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_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

Reply via email to