Dear all,

the attached patch fixes bogus errors with CLASS variables in BLOCK DATA
that showed up because some compiler-generated components were not
declared as artificial.

Furthermore, a warning can be emitted for variables declared but not in
a COMMON block if the option "-Wunused-variable" is set.

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

Thanks,
Harald

From dba6e9bcf284d1d875529520cd7ae52230c1e65b Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anl...@gmx.de>
Date: Sat, 25 Jan 2025 19:59:56 +0100
Subject: [PATCH] Fortran: fix issues with variables in BLOCK DATA [PR58857]

	PR fortran/58857

gcc/fortran/ChangeLog:

	* class.cc (gfc_find_derived_vtab): Declare some frontend generated
	variables and procedures (_vtab, _copy, _deallocate) as artificial.
	(find_intrinsic_vtab): Likewise.
	* trans-decl.cc (check_block_data_decls): New helper function.
	(gfc_generate_block_data): Use it to emit warnings for variables
	declared in a BLOCK DATA program unit but not in a COMMON block.

gcc/testsuite/ChangeLog:

	* gfortran.dg/uncommon_block_data_2.f90: New test.
---
 gcc/fortran/class.cc                          |  4 ++++
 gcc/fortran/trans-decl.cc                     | 23 +++++++++++++++++++
 .../gfortran.dg/uncommon_block_data_2.f90     | 12 ++++++++++
 3 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/uncommon_block_data_2.f90

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 97ff54df5e1..df18601e45b 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -2498,6 +2498,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 	  vtab->attr.save = SAVE_IMPLICIT;
 	  vtab->attr.vtab = 1;
 	  vtab->attr.access = ACCESS_PUBLIC;
+	  vtab->attr.artificial = 1;
 	  gfc_set_sym_referenced (vtab);
 	  free (name);
 	  name = xasprintf ("__vtype_%s", tname);
@@ -2610,6 +2611,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 		goto cleanup;
 	      c->attr.proc_pointer = 1;
 	      c->attr.access = ACCESS_PRIVATE;
+	      c->attr.artificial = 1;
 	      c->tb = XCNEW (gfc_typebound_proc);
 	      c->tb->ppc = 1;
 	      if (derived->attr.unlimited_polymorphic
@@ -2687,6 +2689,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 		goto cleanup;
 	      c->attr.proc_pointer = 1;
 	      c->attr.access = ACCESS_PRIVATE;
+	      c->attr.artificial = 1;
 	      c->tb = XCNEW (gfc_typebound_proc);
 	      c->tb->ppc = 1;
 	      if (derived->attr.unlimited_polymorphic || derived->attr.abstract
@@ -2951,6 +2954,7 @@ find_intrinsic_vtab (gfc_typespec *ts)
 		goto cleanup;
 	      c->attr.proc_pointer = 1;
 	      c->attr.access = ACCESS_PRIVATE;
+	      c->attr.artificial = 1;
 	      c->tb = XCNEW (gfc_typebound_proc);
 	      c->tb->ppc = 1;
 
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 97bb0a41858..b8fc9a1d89c 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -8295,6 +8295,26 @@ gfc_generate_constructors (void)
 #endif
 }
 
+
+/* Helper function for checking of variables declared in a BLOCK DATA program
+   unit.  */
+
+static void
+check_block_data_decls (gfc_symbol * sym)
+{
+  if (warn_unused_variable
+      && sym->attr.flavor == FL_VARIABLE
+      && !sym->attr.in_common
+      && !sym->attr.artificial)
+    {
+      gfc_warning (OPT_Wunused_variable,
+		   "Symbol %qs at %L is declared in a BLOCK DATA "
+		   "program unit but is not in a COMMON block",
+		   sym->name, &sym->declared_at);
+    }
+}
+
+
 /* Translates a BLOCK DATA program unit. This means emitting the
    commons contained therein plus their initializations. We also emit
    a globally visible symbol to make sure that each BLOCK DATA program
@@ -8315,6 +8335,9 @@ gfc_generate_block_data (gfc_namespace * ns)
   /* Process the DATA statements.  */
   gfc_trans_common (ns);
 
+  /* Check for variables declared in BLOCK DATA but not used in COMMON.  */
+  gfc_traverse_ns (ns, check_block_data_decls);
+
   /* Create a global symbol with the mane of the block data.  This is to
      generate linker errors if the same name is used twice.  It is never
      really used.  */
diff --git a/gcc/testsuite/gfortran.dg/uncommon_block_data_2.f90 b/gcc/testsuite/gfortran.dg/uncommon_block_data_2.f90
new file mode 100644
index 00000000000..7b1a0b39a14
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/uncommon_block_data_2.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! { dg-additional-options "-Wunused-variable" }
+!
+! PR fortran/58857
+
+BLOCK DATA valid
+  integer  :: i
+  integer  :: n  ! { dg-warning "not in a COMMON block" }
+  class(*) :: zz ! { dg-warning "not in a COMMON block" }
+  pointer  :: zz
+  common /com/ i, r
+END BLOCK DATA valid
-- 
2.43.0

Reply via email to