[flang-commits] [flang] [Flang] Handle ambiguous types in generic interfaces (PR #221861)
via flang-commits
flang-commits at lists.llvm.org
Mon Sep 7 18:32:55 PDT 2026
https://github.com/keepyixiao created https://github.com/llvm/llvm-project/pull/221861
A generic interface may retain a homonymous derived type whose symbol has become a UseErrorDetails symbol due to ambiguous USE association. The semantic checks assumed that this symbol was still a valid derived type and could dereference a null scope, causing the compiler to crash.
Check that the generic's associated symbol resolves to DerivedTypeDetails and has a scope before emitting the derived-type warning. Also check USE association errors on the resolved derived-type candidate rather than on the generic symbol.
Extend bug168099.f90 with regression tests covering an unused ambiguous derived type, explicit references in both USE orders, and continued use of the generic procedure.
Fixes https://github.com/llvm/llvm-project/issues/209508
>From 3dca0f224a45fefcd76382966ac4fb2fc06e3e4b Mon Sep 17 00:00:00 2001
From: yixiao <yixiao at hygon.cn>
Date: Mon, 7 Sep 2026 21:21:50 +0800
Subject: [PATCH] [Flang] Handle ambiguous types in generic interfaces
A generic interface may retain a homonymous derived type whose symbol has
become a UseErrorDetails symbol due to ambiguous USE association. The
semantic checks assumed that this symbol was still a valid derived type
and could dereference a null scope, causing the compiler to crash.
Check that the generic's associated symbol resolves to DerivedTypeDetails
and has a scope before emitting the derived-type warning. Also check USE
association errors on the resolved derived-type candidate rather than on
the generic symbol.
Extend bug168099.f90 with regression tests covering an unused ambiguous
derived type, explicit references in both USE orders, and continued use
of the generic procedure.
---
flang/lib/Semantics/resolve-names.cpp | 21 ++++++++-----
flang/test/Semantics/bug168099.f90 | 44 +++++++++++++++++++++++++++
flang/test/Semantics/resolve18.f90 | 2 +-
3 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 6517232a1e21c..76ade77dafe81 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -5100,15 +5100,20 @@ void InterfaceVisitor::CheckGenericProcedures(Symbol &generic) {
function = &specific;
} else if (!subroutine && specific.test(Symbol::Flag::Subroutine)) {
subroutine = &specific;
- if (details.derivedType() &&
+ // A generic can retain an ambiguous homonymous derived type as a
+ // UseErrorDetails symbol. It is not a derived type for this warning.
+ if (const Symbol * derivedType{details.derivedType()}; derivedType &&
+ derivedType->GetUltimate().has<DerivedTypeDetails>() &&
context().ShouldWarn(
common::LanguageFeature::SubroutineAndFunctionSpecifics) &&
!InModuleFile()) {
- SayDerivedType(generic.name(),
- "Generic interface '%s' should only contain functions due to derived type with same name"_warn_en_US,
- *details.derivedType()->GetUltimate().scope())
- .set_languageFeature(
- common::LanguageFeature::SubroutineAndFunctionSpecifics);
+ if (const Scope * typeScope{derivedType->GetUltimate().scope()}) {
+ SayDerivedType(generic.name(),
+ "Generic interface '%s' should only contain functions due to derived type with same name"_warn_en_US,
+ *typeScope)
+ .set_languageFeature(
+ common::LanguageFeature::SubroutineAndFunctionSpecifics);
+ }
}
}
if (function && subroutine) { // F'2023 C1514
@@ -8566,7 +8571,9 @@ std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
// type name.
outer.add_importName(name.source);
}
- if (CheckUseError(name)) {
+ // name.symbol can remain the generic while symbol is its homonymous
+ // derived-type candidate, which may carry a USE-association error.
+ if (HadUseError(context(), name.source, symbol)) {
return std::nullopt;
} else if (symbol->GetUltimate().has<DerivedTypeDetails>()) {
return DerivedTypeSpec{name.source, *symbol};
diff --git a/flang/test/Semantics/bug168099.f90 b/flang/test/Semantics/bug168099.f90
index bc08933d7a1a6..ae93638654512 100644
--- a/flang/test/Semantics/bug168099.f90
+++ b/flang/test/Semantics/bug168099.f90
@@ -26,3 +26,47 @@ program main
!ERROR: Reference to 'pair' is ambiguous
type(pair) error
end
+
+module m4
+ type pair_subroutine
+ end type
+ !WARNING: Generic interface 'pair_subroutine' should only contain functions due to derived type with same name [-Wsubroutine-and-function-specifics]
+ interface pair_subroutine
+ subroutine s(var)
+ end subroutine
+ end interface
+end
+
+module m5
+ type pair_subroutine
+ end type
+end
+
+! The generic remains usable after its homonymous derived type becomes
+! ambiguous due to USE association.
+subroutine test_generic_is_preserved
+ use m4
+ use m5
+ call pair_subroutine(1.)
+end
+
+! An unused ambiguous derived type nested in a generic must not cause a crash
+! while the generic's specific procedures are checked.
+subroutine test_unused_ambiguous_derived_type
+ use m4
+ use m5
+end
+
+subroutine test_ambiguous_derived_type
+ use m4
+ use m5
+ !ERROR: Reference to 'pair_subroutine' is ambiguous
+ type(pair_subroutine) error
+end
+
+subroutine test_ambiguous_derived_type_reverse_use_order
+ use m5
+ use m4
+ !ERROR: Reference to 'pair_subroutine' is ambiguous
+ type(pair_subroutine) error
+end
diff --git a/flang/test/Semantics/resolve18.f90 b/flang/test/Semantics/resolve18.f90
index b0827f88996c7..1ae19a50f6b74 100644
--- a/flang/test/Semantics/resolve18.f90
+++ b/flang/test/Semantics/resolve18.f90
@@ -340,7 +340,7 @@ subroutine s_21_22_a
subroutine s_21_22_b
use m21
use m22
- !ERROR: 'foo' is not a derived type
+ !ERROR: Reference to 'foo' is ambiguous
type(foo) x ! definite error: GNU and Intel catch
end
More information about the flang-commits
mailing list