Dear all,

analyzing the the PR (by Gerhard) turned out to two slightly related
issues.  The first one, where a variable in a COMMON block is falsely
resolved to a derived type declared in the host, leads to a false
freeing of the symbol, resulting in memory corruption and ICE.
If we already know that the symbol is in a common block, we may
just skip that interface search.

The other issue is a resolution issue, where the derived type
declared in the host is used in a variable declaration in the
procedure (as type or class), and a variable of the same name
as the derived type is used in a common block but later resolves
to a basic type, without a proper detection of the conflict.
But as this issue is found to be independent of the presence of
a COMMON block, I have opened a separate issue (pr118709) for it.

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

Thanks,
Harald

From 3ab31890f81d24b0231da6d9a5dc29ea316e364d Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anl...@gmx.de>
Date: Thu, 30 Jan 2025 22:21:19 +0100
Subject: [PATCH] Fortran: host association issue with symbol in COMMON block
 [PR108454]

When resolving a flavorless symbol that is already registered with a COMMON
block, and which neither has the intrinsic, generic, or external attribute,
skip searching among interfaces to avoid false resolution to a derived type
of the same name.

	PR fortran/108454

gcc/fortran/ChangeLog:

	* resolve.cc (resolve_common_blocks): Initialize variable.
	(resolve_symbol): If a symbol is already registered with a COMMON
	block, do not search for an interface with the same name.

gcc/testsuite/ChangeLog:

	* gfortran.dg/common_29.f90: New test.
---
 gcc/fortran/resolve.cc                  |  9 ++++++-
 gcc/testsuite/gfortran.dg/common_29.f90 | 34 +++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/common_29.f90

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 12a623da851..f2eef12199c 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -1049,7 +1049,7 @@ resolve_common_vars (gfc_common_head *common_block, bool named_common)
 static void
 resolve_common_blocks (gfc_symtree *common_root)
 {
-  gfc_symbol *sym;
+  gfc_symbol *sym = NULL;
   gfc_gsymbol * gsym;
 
   if (common_root == NULL)
@@ -17693,6 +17693,12 @@ resolve_symbol (gfc_symbol *sym)
 	  && sym->attr.if_source == IFSRC_UNKNOWN
 	  && sym->ts.type == BT_UNKNOWN))
     {
+      /* A symbol in a common block might not have been resolved yet properly.
+	 Do not try to find an interface with the same name.  */
+      if (sym->attr.flavor == FL_UNKNOWN && !sym->attr.intrinsic
+	  && !sym->attr.generic && !sym->attr.external
+	  && sym->attr.in_common)
+	goto skip_interfaces;
 
     /* If we find that a flavorless symbol is an interface in one of the
        parent namespaces, find its symtree in this namespace, free the
@@ -17716,6 +17722,7 @@ resolve_symbol (gfc_symbol *sym)
 	    }
 	}
 
+skip_interfaces:
       /* Otherwise give it a flavor according to such attributes as
 	 it has.  */
       if (sym->attr.flavor == FL_UNKNOWN && sym->attr.external == 0
diff --git a/gcc/testsuite/gfortran.dg/common_29.f90 b/gcc/testsuite/gfortran.dg/common_29.f90
new file mode 100644
index 00000000000..66f2a18a483
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/common_29.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! PR fortran/108454
+!
+! Contributed by G.Steinmetz
+
+module m
+  type t
+  end type
+contains
+  subroutine s
+    common t
+  end
+end
+
+module m2
+  implicit none
+  type t
+  end type
+contains
+  subroutine s
+    real :: t
+    common /com/ t
+  end
+end
+
+module m3
+  type t
+  end type
+contains
+  subroutine s
+    type(t) :: x  ! { dg-error "cannot be host associated at .1." }
+    common t      ! { dg-error "incompatible object of the same name" }
+  end
+end
-- 
2.43.0

Reply via email to