[flang-commits] [flang] [flang] Avoid crash in name resolution on erroneous type extension (PR #109312)
via flang-commits
flang-commits at lists.llvm.org
Thu Sep 19 09:56:09 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
Don't crash when a bad Fortran program tries to extend a derived type with previous legitimate forward references but no prior definition.
Fixes https://github.com/llvm/llvm-project/issues/109268.
---
Full diff: https://github.com/llvm/llvm-project/pull/109312.diff
2 Files Affected:
- (modified) flang/lib/Semantics/resolve-names.cpp (+15-10)
- (modified) flang/test/Semantics/bad-forward-type.f90 (+15)
``````````diff
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5414787d85f7f7..b105dbdce911aa 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1204,7 +1204,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
const parser::Name &, const parser::Name *);
Symbol *MakeTypeSymbol(const SourceName &, Details &&);
Symbol *MakeTypeSymbol(const parser::Name &, Details &&);
- bool OkToAddComponent(const parser::Name &, const Symbol * = nullptr);
+ bool OkToAddComponent(const parser::Name &, const Symbol *extends = nullptr);
ParamValue GetParamValue(
const parser::TypeParamValue &, common::TypeParamAttr attr);
void CheckCommonBlockDerivedType(
@@ -5606,7 +5606,7 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
comp.set(Symbol::Flag::ParentComp);
DeclTypeSpec &type{currScope().MakeDerivedType(
DeclTypeSpec::TypeDerived, std::move(*extendsType))};
- type.derivedTypeSpec().set_scope(*extendsSymbol.scope());
+ type.derivedTypeSpec().set_scope(DEREF(extendsSymbol.scope()));
comp.SetType(type);
DerivedTypeDetails &details{symbol.get<DerivedTypeDetails>()};
details.add_component(comp);
@@ -6797,15 +6797,20 @@ std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveExtendsType(
const parser::Name &typeName, const parser::Name *extendsName) {
- if (!extendsName) {
- return std::nullopt;
- } else if (typeName.source == extendsName->source) {
- Say(extendsName->source,
- "Derived type '%s' cannot extend itself"_err_en_US);
- return std::nullopt;
- } else {
- return ResolveDerivedType(*extendsName);
+ if (extendsName) {
+ if (typeName.source == extendsName->source) {
+ Say(extendsName->source,
+ "Derived type '%s' cannot extend itself"_err_en_US);
+ } else if (auto dtSpec{ResolveDerivedType(*extendsName)}) {
+ if (!dtSpec->IsForwardReferenced()) {
+ return dtSpec;
+ }
+ Say(typeName.source,
+ "Derived type '%s' cannot extend type '%s' that has not yet been defined"_err_en_US,
+ typeName.source, extendsName->source);
+ }
}
+ return std::nullopt;
}
Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
diff --git a/flang/test/Semantics/bad-forward-type.f90 b/flang/test/Semantics/bad-forward-type.f90
index 27c6045b0059fa..f379b274e1279b 100644
--- a/flang/test/Semantics/bad-forward-type.f90
+++ b/flang/test/Semantics/bad-forward-type.f90
@@ -97,3 +97,18 @@ subroutine s10
type(undef), pointer :: y
end type
end subroutine s10
+
+subroutine s11
+ !ERROR: Derived type 'undef1' not found
+ type(undef1), pointer :: p
+ type t1
+ !ERROR: The derived type 'undef2' has not been defined
+ type(undef2), pointer :: p
+ end type
+ !ERROR: Derived type 'undef1' not found
+ type, extends(undef1) :: t2
+ end type
+ !ERROR: Derived type 't3' cannot extend type 'undef2' that has not yet been defined
+ type, extends(undef2) :: t3
+ end type
+end subroutine s11
``````````
</details>
https://github.com/llvm/llvm-project/pull/109312
More information about the flang-commits
mailing list