Skip to content

Commit e8335ae

Browse files
authored
[flang] Avoid crash in name resolution on erroneous type extension (llvm#109312)
Don't crash when a bad Fortran program tries to extend a derived type with previous legitimate forward references but no prior definition. Fixes llvm#109268.
1 parent 7513892 commit e8335ae

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
12041204
const parser::Name &, const parser::Name *);
12051205
Symbol *MakeTypeSymbol(const SourceName &, Details &&);
12061206
Symbol *MakeTypeSymbol(const parser::Name &, Details &&);
1207-
bool OkToAddComponent(const parser::Name &, const Symbol * = nullptr);
1207+
bool OkToAddComponent(const parser::Name &, const Symbol *extends = nullptr);
12081208
ParamValue GetParamValue(
12091209
const parser::TypeParamValue &, common::TypeParamAttr attr);
12101210
void CheckCommonBlockDerivedType(
@@ -5606,7 +5606,7 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
56065606
comp.set(Symbol::Flag::ParentComp);
56075607
DeclTypeSpec &type{currScope().MakeDerivedType(
56085608
DeclTypeSpec::TypeDerived, std::move(*extendsType))};
5609-
type.derivedTypeSpec().set_scope(*extendsSymbol.scope());
5609+
type.derivedTypeSpec().set_scope(DEREF(extendsSymbol.scope()));
56105610
comp.SetType(type);
56115611
DerivedTypeDetails &details{symbol.get<DerivedTypeDetails>()};
56125612
details.add_component(comp);
@@ -6797,15 +6797,20 @@ std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
67976797

67986798
std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveExtendsType(
67996799
const parser::Name &typeName, const parser::Name *extendsName) {
6800-
if (!extendsName) {
6801-
return std::nullopt;
6802-
} else if (typeName.source == extendsName->source) {
6803-
Say(extendsName->source,
6804-
"Derived type '%s' cannot extend itself"_err_en_US);
6805-
return std::nullopt;
6806-
} else {
6807-
return ResolveDerivedType(*extendsName);
6800+
if (extendsName) {
6801+
if (typeName.source == extendsName->source) {
6802+
Say(extendsName->source,
6803+
"Derived type '%s' cannot extend itself"_err_en_US);
6804+
} else if (auto dtSpec{ResolveDerivedType(*extendsName)}) {
6805+
if (!dtSpec->IsForwardReferenced()) {
6806+
return dtSpec;
6807+
}
6808+
Say(typeName.source,
6809+
"Derived type '%s' cannot extend type '%s' that has not yet been defined"_err_en_US,
6810+
typeName.source, extendsName->source);
6811+
}
68086812
}
6813+
return std::nullopt;
68096814
}
68106815

68116816
Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {

flang/test/Semantics/bad-forward-type.f90

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,18 @@ subroutine s10
9797
type(undef), pointer :: y
9898
end type
9999
end subroutine s10
100+
101+
subroutine s11
102+
!ERROR: Derived type 'undef1' not found
103+
type(undef1), pointer :: p
104+
type t1
105+
!ERROR: The derived type 'undef2' has not been defined
106+
type(undef2), pointer :: p
107+
end type
108+
!ERROR: Derived type 'undef1' not found
109+
type, extends(undef1) :: t2
110+
end type
111+
!ERROR: Derived type 't3' cannot extend type 'undef2' that has not yet been defined
112+
type, extends(undef2) :: t3
113+
end type
114+
end subroutine s11

0 commit comments

Comments
 (0)