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