Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flang] Ensure names resolve in DATA statement objects #82825

Merged
merged 1 commit into from
Mar 2, 2024

Conversation

klausler
Copy link
Contributor

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 23, 2024

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/82825.diff

2 Files Affected:

  • (modified) flang/lib/Semantics/resolve-names.cpp (+15-1)
  • (added) flang/test/Semantics/data22.f90 (+17)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 36deab969456d0..7c2d76239f9ca4 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -8398,6 +8398,7 @@ bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
   Walk(expr);
   return false;
 }
+
 void ResolveNamesVisitor::Post(const parser::Designator &x) {
   ResolveDesignator(x);
 }
@@ -8405,7 +8406,6 @@ void ResolveNamesVisitor::Post(const parser::SubstringInquiry &x) {
   Walk(std::get<parser::SubstringRange>(x.v.t).t);
   ResolveDataRef(std::get<parser::DataRef>(x.v.t));
 }
-
 void ResolveNamesVisitor::Post(const parser::ProcComponentRef &x) {
   ResolveStructureComponent(x.v.thing);
 }
@@ -8413,6 +8413,7 @@ void ResolveNamesVisitor::Post(const parser::TypeGuardStmt &x) {
   DeclTypeSpecVisitor::Post(x);
   ConstructVisitor::Post(x);
 }
+
 bool ResolveNamesVisitor::Pre(const parser::StmtFunctionStmt &x) {
   if (HandleStmtFunction(x)) {
     return false;
@@ -8950,6 +8951,8 @@ void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) {
 // pointers, are deferred until all of the pertinent specification parts
 // have been visited.  This deferred processing enables the use of forward
 // references in these circumstances.
+// Data statement objects with implicit derived types are finally
+// resolved here.
 class DeferredCheckVisitor {
 public:
   explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver)
@@ -9010,6 +9013,16 @@ class DeferredCheckVisitor {
       resolver_.CheckBindings(tbps);
     }
   }
+  bool Pre(const parser::DataStmtObject &) {
+    ++dataStmtObjectNesting_;
+    return true;
+  }
+  void Post(const parser::DataStmtObject &) { --dataStmtObjectNesting_; }
+  void Post(const parser::Designator &x) {
+    if (dataStmtObjectNesting_ > 0) {
+      resolver_.ResolveDesignator(x);
+    }
+  }
 
 private:
   void Init(const parser::Name &name,
@@ -9032,6 +9045,7 @@ class DeferredCheckVisitor {
 
   ResolveNamesVisitor &resolver_;
   bool pushedScope_{false};
+  int dataStmtObjectNesting_{0};
 };
 
 // Perform checks and completions that need to happen after all of
diff --git a/flang/test/Semantics/data22.f90 b/flang/test/Semantics/data22.f90
new file mode 100644
index 00000000000000..365958dbe7579c
--- /dev/null
+++ b/flang/test/Semantics/data22.f90
@@ -0,0 +1,17 @@
+! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
+! Ensure that implicitly typed DATA statement objects with derived
+! types get their symbols resolved by the end of the name resolution pass.
+! CHECK: x1 (Implicit, InDataStmt) size=4 offset=0: ObjectEntity type: TYPE(t1) shape: 1_8:1_8 init:[t1::t1(n=123_4)]
+! CHECK: x2 (InDataStmt) size=4 offset=4: ObjectEntity type: TYPE(t2) shape: 1_8:1_8 init:[t2::t2(m=456_4)]
+implicit type(t1)(x)
+type t1
+  integer n
+end type
+dimension x1(1), x2(1)
+data x1(1)%n /123/
+data x2(1)%m /456/
+type t2
+  integer m
+end type
+type(t2) x2
+end

Copy link
Contributor

@psteinfeld psteinfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All builds and tests correctly and looks good.

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 llvm#82069.
@klausler klausler merged commit 189d89a into llvm:main Mar 2, 2024
3 of 4 checks passed
@klausler klausler deleted the bug82069 branch March 2, 2024 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Flang] Incorrect diagnose of DATA statement to initialize implicitly typed and subscripted components
3 participants