Skip to content

Commit 2101c27

Browse files
committed
[flang] Ensure names resolve in DATA statement objects
When DATA statement objects have derived types obtained by implicit typing rules, their types aren't known until specification part processing is complete. In the case of a derived type, any component name in a designator may still be in need of name resolution. Take care of it in the deferred check visitor that runs at the end of name resolution in each specification and execution part. Fixes #82069.
1 parent 822142f commit 2101c27

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8950,6 +8950,8 @@ void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) {
89508950
// pointers, are deferred until all of the pertinent specification parts
89518951
// have been visited. This deferred processing enables the use of forward
89528952
// references in these circumstances.
8953+
// Data statement objects with implicit derived types are finally
8954+
// resolved here.
89538955
class DeferredCheckVisitor {
89548956
public:
89558957
explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver)
@@ -8965,16 +8967,17 @@ class DeferredCheckVisitor {
89658967
if (Symbol * symbol{name.symbol}) {
89668968
if (Scope * scope{symbol->scope()}) {
89678969
if (scope->IsDerivedType()) {
8968-
resolver_.PushScope(*scope);
8969-
pushedScope_ = true;
8970+
CHECK(outerScope_ == nullptr);
8971+
outerScope_ = &resolver_.currScope();
8972+
resolver_.SetScope(*scope);
89708973
}
89718974
}
89728975
}
89738976
}
89748977
void Post(const parser::EndTypeStmt &) {
8975-
if (pushedScope_) {
8976-
resolver_.PopScope();
8977-
pushedScope_ = false;
8978+
if (outerScope_) {
8979+
resolver_.SetScope(*outerScope_);
8980+
outerScope_ = nullptr;
89788981
}
89798982
}
89808983

@@ -9006,10 +9009,20 @@ class DeferredCheckVisitor {
90069009
resolver_.CheckExplicitInterface(tbps.interfaceName);
90079010
}
90089011
void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
9009-
if (pushedScope_) {
9012+
if (outerScope_) {
90109013
resolver_.CheckBindings(tbps);
90119014
}
90129015
}
9016+
bool Pre(const parser::DataStmtObject &) {
9017+
++dataStmtObjectNesting_;
9018+
return true;
9019+
}
9020+
void Post(const parser::DataStmtObject &) { --dataStmtObjectNesting_; }
9021+
void Post(const parser::Designator &x) {
9022+
if (dataStmtObjectNesting_ > 0) {
9023+
resolver_.ResolveDesignator(x);
9024+
}
9025+
}
90139026

90149027
private:
90159028
void Init(const parser::Name &name,
@@ -9031,7 +9044,8 @@ class DeferredCheckVisitor {
90319044
}
90329045

90339046
ResolveNamesVisitor &resolver_;
9034-
bool pushedScope_{false};
9047+
Scope *outerScope_{nullptr};
9048+
int dataStmtObjectNesting_{0};
90359049
};
90369050

90379051
// Perform checks and completions that need to happen after all of

flang/test/Semantics/data22.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
2+
! Ensure that implicitly typed DATA statement objects with derived
3+
! types get their symbols resolved by the end of the name resolution pass.
4+
! CHECK: x1 (Implicit, InDataStmt) size=4 offset=0: ObjectEntity type: TYPE(t1) shape: 1_8:1_8 init:[t1::t1(n=123_4)]
5+
! CHECK: x2 (InDataStmt) size=4 offset=4: ObjectEntity type: TYPE(t2) shape: 1_8:1_8 init:[t2::t2(m=456_4)]
6+
implicit type(t1)(x)
7+
type t1
8+
integer n
9+
end type
10+
dimension x1(1), x2(1)
11+
data x1(1)%n /123/
12+
data x2(1)%m /456/
13+
type t2
14+
integer m
15+
end type
16+
type(t2) x2
17+
end

0 commit comments

Comments
 (0)