https://gcc.gnu.org/g:b207851b2d1b26b3b9ee7b8cfab637ee531acfc1

commit r17-2339-gb207851b2d1b26b3b9ee7b8cfab637ee531acfc1
Author: Paul Thomas <[email protected]>
Date:   Sun Jul 12 12:27:29 2026 +0100

    Fortran: Constraints involving coarray ultimate components 
[PR101951,PR101967]
    
    2026-07-12  Steve Kargl  <[email protected]>
    
    gcc/fortran
            PR fortran/101951
            PR fortran/101967
            * match.cc (gfc_match_allocate): It is an error if the type-spec
            derived type or the source expr has a coarray ultimate component.
            Substitute 'typespec' with 'type-spec' in error messages for
            consistency with standards.
    
    gcc/testsuite/
            PR fortran/101951
            * gfortran.dg/f2018c937.f90: New test.
            PR fortran/101967
            * gfortran.dg/f2018c949.f90: New test.
    
            * gfortran.dg/allocate_alloc_opt_4.f90: Substitute 'typespec' with
            'type-spec' in error checks.
            * gfortran.dg/allocate_derived_1.f90: Ditto.

Diff:
---
 gcc/fortran/match.cc                               | 31 +++++++++++++++++++---
 gcc/testsuite/gfortran.dg/allocate_alloc_opt_4.f90 |  2 +-
 gcc/testsuite/gfortran.dg/allocate_derived_1.f90   | 10 +++----
 gcc/testsuite/gfortran.dg/f2018c937.f90            | 10 +++++++
 gcc/testsuite/gfortran.dg/f2018c949.f90            | 13 +++++++++
 5 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 4471c1b13b57..b09d348e6b52 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -5249,7 +5249,7 @@ gfc_match_allocate (void)
 
       if (gfc_match (" :: ") == MATCH_YES)
        {
-         if (!gfc_notify_std (GFC_STD_F2003, "typespec in ALLOCATE at %L",
+         if (!gfc_notify_std (GFC_STD_F2003, "type-spec in ALLOCATE at %L",
                               &old_locus))
            goto cleanup;
 
@@ -5281,6 +5281,16 @@ gfc_match_allocate (void)
          ts.type = BT_UNKNOWN;
          gfc_current_locus = old_locus;
        }
+
+      /* F2018:C937 (R927) type-spec shall not specify a type that has a
+        coarray ultimate component.  Similar text in F2008:C640 (R626).  */
+      if (ts.type == BT_DERIVED
+         && ts.u.derived->attr.coarray_comp)
+       {
+         gfc_error ("Type-spec at %L has a coarray ultimate component",
+                    &old_locus);
+         goto cleanup;
+       }
     }
 
   for (;;)
@@ -5405,7 +5415,7 @@ gfc_match_allocate (void)
          if (!gfc_type_compatible (&tail->expr->ts, &ts))
            {
              gfc_error ("Type of entity at %L is type incompatible with "
-                        "typespec", &tail->expr->where);
+                        "type-spec", &tail->expr->where);
              goto cleanup;
            }
 
@@ -5413,7 +5423,7 @@ gfc_match_allocate (void)
          if (ts.kind != tail->expr->ts.kind && !UNLIMITED_POLY (tail->expr))
            {
              gfc_error ("Kind type parameter for entity at %L differs from "
-                        "the kind type parameter of the typespec",
+                        "the kind type parameter of the type-spec",
                         &tail->expr->where);
              goto cleanup;
            }
@@ -5508,7 +5518,7 @@ alloc_opt_list:
          /* The next 2 conditionals check C631.  */
          if (ts.type != BT_UNKNOWN)
            {
-             gfc_error ("SOURCE tag at %L conflicts with the typespec at %L",
+             gfc_error ("SOURCE tag at %L conflicts with the type-spec at %L",
                         &tmp->where, &old_locus);
              goto cleanup;
            }
@@ -5519,6 +5529,8 @@ alloc_opt_list:
                                  &tmp->where))
            goto cleanup;
 
+
+
          source = tmp;
          tmp = NULL;
          saw_source = true;
@@ -5568,6 +5580,17 @@ alloc_opt_list:
   if (gfc_match (" )%t") != MATCH_YES)
     goto syntax;
 
+  /* C949 (R930) The declared type of source-expr shall not have a
+     coarray ultimate component. */
+  if (source
+      && source->ts.type == BT_DERIVED
+      && source->ts.u.derived->attr.coarray_comp)
+    {
+      gfc_error ("Declared type of source expression at %L has a coarray "
+                "ultimate component", &source->where);
+      goto cleanup;
+    }
+
   /* Check F08:C637.  */
   if (source && mold)
     {
diff --git a/gcc/testsuite/gfortran.dg/allocate_alloc_opt_4.f90 
b/gcc/testsuite/gfortran.dg/allocate_alloc_opt_4.f90
index ee6c3635912d..b98352a91043 100644
--- a/gcc/testsuite/gfortran.dg/allocate_alloc_opt_4.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_alloc_opt_4.f90
@@ -15,7 +15,7 @@ program a
 
   allocate(i(4), source=42, source=n) ! { dg-error "Redundant SOURCE tag 
found" }
 
-  allocate(integer(4) :: i(4), source=n) ! { dg-error "conflicts with the 
typespec" }
+  allocate(integer(4) :: i(4), source=n) ! { dg-error "conflicts with the 
type-spec" }
 
   allocate(i(4), j(n), source=n) ! { dg-error "Fortran 2008: SOURCE tag at .1. 
with more than a single allocate object" }
 
diff --git a/gcc/testsuite/gfortran.dg/allocate_derived_1.f90 
b/gcc/testsuite/gfortran.dg/allocate_derived_1.f90
index d2c65ffa38bd..12633eb5dc7a 100644
--- a/gcc/testsuite/gfortran.dg/allocate_derived_1.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_derived_1.f90
@@ -34,16 +34,16 @@
  allocate(t3 :: x(4))
  allocate(tx :: x(5))  ! { dg-error "Error in type-spec at" }
  allocate(u0 :: x(6))  ! { dg-error "may not be ABSTRACT" }
- allocate(v1 :: x(7))  ! { dg-error "is type incompatible with typespec" }
+ allocate(v1 :: x(7))  ! { dg-error "is type incompatible with type-spec" }
 
  allocate(      y(1))
- allocate(t1 :: y(2))  ! { dg-error "is type incompatible with typespec" }
+ allocate(t1 :: y(2))  ! { dg-error "is type incompatible with type-spec" }
  allocate(t2 :: y(3))
- allocate(t3 :: y(3))  ! { dg-error "is type incompatible with typespec" }
+ allocate(t3 :: y(3))  ! { dg-error "is type incompatible with type-spec" }
 
  allocate(      z(1))
- allocate(t1 :: z(2))  ! { dg-error "is type incompatible with typespec" }
- allocate(t2 :: z(3))  ! { dg-error "is type incompatible with typespec" }
+ allocate(t1 :: z(2))  ! { dg-error "is type incompatible with type-spec" }
+ allocate(t2 :: z(3))  ! { dg-error "is type incompatible with type-spec" }
  allocate(t3 :: z(4))
 
 end
diff --git a/gcc/testsuite/gfortran.dg/f2018c937.f90 
b/gcc/testsuite/gfortran.dg/f2018c937.f90
new file mode 100644
index 000000000000..2a789a0e2d2a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/f2018c937.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=single" }
+! https://mailman.j3-fortran.org/pipermail/j3/2021-August/013230.html
+program foo
+   type :: a_t
+      integer, allocatable :: n[:]
+   end type
+   class(*), allocatable :: a
+   allocate(a_t :: a)         ! { dg-error "coarray ultimate component" }
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/f2018c949.f90 
b/gcc/testsuite/gfortran.dg/f2018c949.f90
new file mode 100644
index 000000000000..14a1facbd73f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/f2018c949.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=single" }
+program main
+  type :: type
+    integer, allocatable :: a[:]
+  end type
+
+  type(type) :: x
+  class(*), allocatable :: y
+
+  allocate(x%a[*])
+  allocate(y, source = x) !{ dg-error "coarray ultimate component" }
+end

Reply via email to