[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:33:36 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: nudt_yixiao (keepyixiao)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/221861.diff
3 Files Affected:
- (modified) flang/lib/Semantics/resolve-names.cpp (+14-7)
- (modified) flang/test/Semantics/bug168099.f90 (+44)
- (modified) flang/test/Semantics/resolve18.f90 (+1-1)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/221861
More information about the flang-commits
mailing list