Dear all,

due to an oversight in the Fortran standard before 2018,
empty derived types with bind(C) attribute were explicitly
(deliberately?) accepted by gfortran, giving a warning that
the companion processor might not provide an interoperating
entity.

In the PR, Tobias pointed to a discussion on the J3 ML that
there was a defect in older standards.  The attached patch
now generates an error when -std=f20xx is specified, and
continues to generate a warning otherwise.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald

From 5c38ce50ed7cca905401f6fa6506b47fd79a7739 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anl...@gmx.de>
Date: Sun, 2 Mar 2025 22:20:28 +0100
Subject: [PATCH] Fortran: reject empty derived type with bind(C) attribute
 [PR101577]

	PR fortran/101577

gcc/fortran/ChangeLog:

	* symbol.cc (verify_bind_c_derived_type): Generate error message
	for derived type with no components in standard conformance mode,
	indicating that this is a GNU extension.

gcc/testsuite/ChangeLog:

	* gfortran.dg/empty_derived_type.f90: Adjust dg-options.
	* gfortran.dg/empty_derived_type_2.f90: New test.
---
 gcc/fortran/symbol.cc                         | 22 ++++++++++++++++---
 .../gfortran.dg/empty_derived_type.f90        |  1 +
 .../gfortran.dg/empty_derived_type_2.f90      | 11 ++++++++++
 3 files changed, 31 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/empty_derived_type_2.f90

diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index c6894810bce..9ddf13b3f0d 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -4624,12 +4624,28 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym)
      entity may be defined by means of C and the Fortran entity is said
      to be interoperable with the C entity.  There does not have to be such
      an interoperating C entity."
+
+     However, later discussion on the J3 mailing list
+     (https://mailman.j3-fortran.org/pipermail/j3/2021-July/013190.html)
+     found this to be a defect, and Fortran 2018 added in section 18.3.4
+     the following constraint:
+     "C1805: A derived type with the BIND attribute shall have at least one
+     component."
+
+     We thus allow empty derived types only as GNU extension while giving a
+     warning by default, or reject empty types in standard conformance mode.
   */
   if (curr_comp == NULL)
     {
-      gfc_warning (0, "Derived type %qs with BIND(C) attribute at %L is empty, "
-		   "and may be inaccessible by the C companion processor",
-		   derived_sym->name, &(derived_sym->declared_at));
+      if (!gfc_notify_std (GFC_STD_GNU, "Derived type %qs with BIND(C) "
+			   "attribute at %L has no components",
+			   derived_sym->name, &(derived_sym->declared_at)))
+	return false;
+      else if (!pedantic)
+	gfc_warning (0, "Derived type %qs with BIND(C) attribute at %L "
+		     "is empty, and may be inaccessible by the C "
+		     "companion processor",
+		     derived_sym->name, &(derived_sym->declared_at));
       derived_sym->ts.is_c_interop = 1;
       derived_sym->attr.is_bind_c = 1;
       return true;
diff --git a/gcc/testsuite/gfortran.dg/empty_derived_type.f90 b/gcc/testsuite/gfortran.dg/empty_derived_type.f90
index 6bf616c2c6a..496262de2cd 100644
--- a/gcc/testsuite/gfortran.dg/empty_derived_type.f90
+++ b/gcc/testsuite/gfortran.dg/empty_derived_type.f90
@@ -1,4 +1,5 @@
 ! { dg-do compile }
+! { dg-options "" }
 module stuff
    implicit none
    type, bind(C) :: junk ! { dg-warning "may be inaccessible by the C companion" }
diff --git a/gcc/testsuite/gfortran.dg/empty_derived_type_2.f90 b/gcc/testsuite/gfortran.dg/empty_derived_type_2.f90
new file mode 100644
index 00000000000..1ef56da4c25
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/empty_derived_type_2.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-additional-options "-std=f2018" }
+!
+! PR fortran/101577
+!
+! Contributed by Tobias Burnus
+
+type, bind(C) :: t ! { dg-error "has no components" }
+   ! Empty!
+end type t
+end
-- 
2.43.0

Reply via email to