Skip to content

Conversation

@akuhlens
Copy link
Contributor

This PR:

  • makes Cray pointer declarations shadow previous bindings instead of modifying them,
  • errors when the pointee of a cray pointee has the SAVE attribute, and
  • adds a missing newline after dumping the list of cray pointers in a scope.

Closes #135579

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:openmp flang:semantics labels Apr 22, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 22, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Andre Kuhlenschmidt (akuhlens)

Changes

This PR:

  • makes Cray pointer declarations shadow previous bindings instead of modifying them,
  • errors when the pointee of a cray pointee has the SAVE attribute, and
  • adds a missing newline after dumping the list of cray pointers in a scope.

Closes #135579


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

5 Files Affected:

  • (modified) flang/lib/Semantics/check-declarations.cpp (+11-1)
  • (modified) flang/lib/Semantics/resolve-names.cpp (+1-1)
  • (modified) flang/lib/Semantics/semantics.cpp (+1)
  • (modified) flang/test/Lower/OpenMP/cray-pointers01.f90 (+1-1)
  • (modified) flang/test/Semantics/declarations08.f90 (+6)
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 8d5e034f8624b..6cc4665532385 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -963,7 +963,17 @@ void CheckHelper::CheckObjectEntity(
         "'%s' is a data object and may not be EXTERNAL"_err_en_US,
         symbol.name());
   }
-
+  if (symbol.test(Symbol::Flag::CrayPointee)) {
+    // NB, IsSaved was too smart here.
+    if (details.init()) {
+      messages_.Say(
+          "Cray pointee '%s' may not be initialized"_err_en_US, symbol.name());
+    } else if (symbol.attrs().test(Attr::SAVE) ||
+        symbol.implicitAttrs().test(Attr::SAVE)) {
+      messages_.Say(
+          "Cray pointee '%s' may not be SAVE"_err_en_US, symbol.name());
+    }
+  }
   if (derived) {
     bool isUnsavedLocal{
         isLocalVariable && !IsAllocatable(symbol) && !IsSaved(symbol)};
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f1d2ba4078236..e0550b3724bef 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6650,7 +6650,7 @@ bool DeclarationVisitor::Pre(const parser::BasedPointer &) {
 
 void DeclarationVisitor::Post(const parser::BasedPointer &bp) {
   const parser::ObjectName &pointerName{std::get<0>(bp.t)};
-  auto *pointer{FindSymbol(pointerName)};
+  auto *pointer{FindInScope(pointerName)};
   if (!pointer) {
     pointer = &MakeSymbol(pointerName, ObjectEntityDetails{});
   } else if (!ConvertToObjectEntity(*pointer)) {
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 10a01039ea0ae..e07054f8ec564 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -731,6 +731,7 @@ void DoDumpSymbols(llvm::raw_ostream &os, const Scope &scope, int indent) {
     for (const auto &[pointee, pointer] : scope.crayPointers()) {
       os << " (" << pointer->name() << ',' << pointee << ')';
     }
+    os << '\n';
   }
   for (const auto &pair : scope.commonBlocks()) {
     const auto &symbol{*pair.second};
diff --git a/flang/test/Lower/OpenMP/cray-pointers01.f90 b/flang/test/Lower/OpenMP/cray-pointers01.f90
index 87692ccbadfe3..d3a5a3cdd39a3 100644
--- a/flang/test/Lower/OpenMP/cray-pointers01.f90
+++ b/flang/test/Lower/OpenMP/cray-pointers01.f90
@@ -33,7 +33,7 @@ subroutine set_cray_pointer
 end module
 
 program test_cray_pointers_01
-  real*8, save :: var(*)
+  real*8 :: var(*)
   ! CHECK: %[[BOX_ALLOCA:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf64>>>
   ! CHECK: %[[IVAR_ALLOCA:.*]] = fir.alloca i64 {bindc_name = "ivar", uniq_name = "_QFEivar"}
   ! CHECK: %[[IVAR_DECL_01:.*]]:2 = hlfir.declare %[[IVAR_ALLOCA]] {uniq_name = "_QFEivar"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
diff --git a/flang/test/Semantics/declarations08.f90 b/flang/test/Semantics/declarations08.f90
index bd14131b33c28..140ff710228c1 100644
--- a/flang/test/Semantics/declarations08.f90
+++ b/flang/test/Semantics/declarations08.f90
@@ -5,4 +5,10 @@
 !ERROR: Cray pointee 'x' may not be a member of a COMMON block
 common x
 equivalence(y,z)
+!ERROR: Cray pointee 'v' may not be initialized
+real :: v = 42.0
+pointer(p,v)
+!ERROR: Cray pointee 'u' may not be SAVE
+save u
+pointer(p, u)
 end

@llvmbot
Copy link
Member

llvmbot commented Apr 22, 2025

@llvm/pr-subscribers-flang-openmp

Author: Andre Kuhlenschmidt (akuhlens)

Changes

This PR:

  • makes Cray pointer declarations shadow previous bindings instead of modifying them,
  • errors when the pointee of a cray pointee has the SAVE attribute, and
  • adds a missing newline after dumping the list of cray pointers in a scope.

Closes #135579


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

5 Files Affected:

  • (modified) flang/lib/Semantics/check-declarations.cpp (+11-1)
  • (modified) flang/lib/Semantics/resolve-names.cpp (+1-1)
  • (modified) flang/lib/Semantics/semantics.cpp (+1)
  • (modified) flang/test/Lower/OpenMP/cray-pointers01.f90 (+1-1)
  • (modified) flang/test/Semantics/declarations08.f90 (+6)
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 8d5e034f8624b..6cc4665532385 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -963,7 +963,17 @@ void CheckHelper::CheckObjectEntity(
         "'%s' is a data object and may not be EXTERNAL"_err_en_US,
         symbol.name());
   }
-
+  if (symbol.test(Symbol::Flag::CrayPointee)) {
+    // NB, IsSaved was too smart here.
+    if (details.init()) {
+      messages_.Say(
+          "Cray pointee '%s' may not be initialized"_err_en_US, symbol.name());
+    } else if (symbol.attrs().test(Attr::SAVE) ||
+        symbol.implicitAttrs().test(Attr::SAVE)) {
+      messages_.Say(
+          "Cray pointee '%s' may not be SAVE"_err_en_US, symbol.name());
+    }
+  }
   if (derived) {
     bool isUnsavedLocal{
         isLocalVariable && !IsAllocatable(symbol) && !IsSaved(symbol)};
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f1d2ba4078236..e0550b3724bef 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6650,7 +6650,7 @@ bool DeclarationVisitor::Pre(const parser::BasedPointer &) {
 
 void DeclarationVisitor::Post(const parser::BasedPointer &bp) {
   const parser::ObjectName &pointerName{std::get<0>(bp.t)};
-  auto *pointer{FindSymbol(pointerName)};
+  auto *pointer{FindInScope(pointerName)};
   if (!pointer) {
     pointer = &MakeSymbol(pointerName, ObjectEntityDetails{});
   } else if (!ConvertToObjectEntity(*pointer)) {
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 10a01039ea0ae..e07054f8ec564 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -731,6 +731,7 @@ void DoDumpSymbols(llvm::raw_ostream &os, const Scope &scope, int indent) {
     for (const auto &[pointee, pointer] : scope.crayPointers()) {
       os << " (" << pointer->name() << ',' << pointee << ')';
     }
+    os << '\n';
   }
   for (const auto &pair : scope.commonBlocks()) {
     const auto &symbol{*pair.second};
diff --git a/flang/test/Lower/OpenMP/cray-pointers01.f90 b/flang/test/Lower/OpenMP/cray-pointers01.f90
index 87692ccbadfe3..d3a5a3cdd39a3 100644
--- a/flang/test/Lower/OpenMP/cray-pointers01.f90
+++ b/flang/test/Lower/OpenMP/cray-pointers01.f90
@@ -33,7 +33,7 @@ subroutine set_cray_pointer
 end module
 
 program test_cray_pointers_01
-  real*8, save :: var(*)
+  real*8 :: var(*)
   ! CHECK: %[[BOX_ALLOCA:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf64>>>
   ! CHECK: %[[IVAR_ALLOCA:.*]] = fir.alloca i64 {bindc_name = "ivar", uniq_name = "_QFEivar"}
   ! CHECK: %[[IVAR_DECL_01:.*]]:2 = hlfir.declare %[[IVAR_ALLOCA]] {uniq_name = "_QFEivar"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
diff --git a/flang/test/Semantics/declarations08.f90 b/flang/test/Semantics/declarations08.f90
index bd14131b33c28..140ff710228c1 100644
--- a/flang/test/Semantics/declarations08.f90
+++ b/flang/test/Semantics/declarations08.f90
@@ -5,4 +5,10 @@
 !ERROR: Cray pointee 'x' may not be a member of a COMMON block
 common x
 equivalence(y,z)
+!ERROR: Cray pointee 'v' may not be initialized
+real :: v = 42.0
+pointer(p,v)
+!ERROR: Cray pointee 'u' may not be SAVE
+save u
+pointer(p, u)
 end

@llvmbot
Copy link
Member

llvmbot commented Apr 22, 2025

@llvm/pr-subscribers-flang-semantics

Author: Andre Kuhlenschmidt (akuhlens)

Changes

This PR:

  • makes Cray pointer declarations shadow previous bindings instead of modifying them,
  • errors when the pointee of a cray pointee has the SAVE attribute, and
  • adds a missing newline after dumping the list of cray pointers in a scope.

Closes #135579


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

5 Files Affected:

  • (modified) flang/lib/Semantics/check-declarations.cpp (+11-1)
  • (modified) flang/lib/Semantics/resolve-names.cpp (+1-1)
  • (modified) flang/lib/Semantics/semantics.cpp (+1)
  • (modified) flang/test/Lower/OpenMP/cray-pointers01.f90 (+1-1)
  • (modified) flang/test/Semantics/declarations08.f90 (+6)
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 8d5e034f8624b..6cc4665532385 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -963,7 +963,17 @@ void CheckHelper::CheckObjectEntity(
         "'%s' is a data object and may not be EXTERNAL"_err_en_US,
         symbol.name());
   }
-
+  if (symbol.test(Symbol::Flag::CrayPointee)) {
+    // NB, IsSaved was too smart here.
+    if (details.init()) {
+      messages_.Say(
+          "Cray pointee '%s' may not be initialized"_err_en_US, symbol.name());
+    } else if (symbol.attrs().test(Attr::SAVE) ||
+        symbol.implicitAttrs().test(Attr::SAVE)) {
+      messages_.Say(
+          "Cray pointee '%s' may not be SAVE"_err_en_US, symbol.name());
+    }
+  }
   if (derived) {
     bool isUnsavedLocal{
         isLocalVariable && !IsAllocatable(symbol) && !IsSaved(symbol)};
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f1d2ba4078236..e0550b3724bef 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6650,7 +6650,7 @@ bool DeclarationVisitor::Pre(const parser::BasedPointer &) {
 
 void DeclarationVisitor::Post(const parser::BasedPointer &bp) {
   const parser::ObjectName &pointerName{std::get<0>(bp.t)};
-  auto *pointer{FindSymbol(pointerName)};
+  auto *pointer{FindInScope(pointerName)};
   if (!pointer) {
     pointer = &MakeSymbol(pointerName, ObjectEntityDetails{});
   } else if (!ConvertToObjectEntity(*pointer)) {
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 10a01039ea0ae..e07054f8ec564 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -731,6 +731,7 @@ void DoDumpSymbols(llvm::raw_ostream &os, const Scope &scope, int indent) {
     for (const auto &[pointee, pointer] : scope.crayPointers()) {
       os << " (" << pointer->name() << ',' << pointee << ')';
     }
+    os << '\n';
   }
   for (const auto &pair : scope.commonBlocks()) {
     const auto &symbol{*pair.second};
diff --git a/flang/test/Lower/OpenMP/cray-pointers01.f90 b/flang/test/Lower/OpenMP/cray-pointers01.f90
index 87692ccbadfe3..d3a5a3cdd39a3 100644
--- a/flang/test/Lower/OpenMP/cray-pointers01.f90
+++ b/flang/test/Lower/OpenMP/cray-pointers01.f90
@@ -33,7 +33,7 @@ subroutine set_cray_pointer
 end module
 
 program test_cray_pointers_01
-  real*8, save :: var(*)
+  real*8 :: var(*)
   ! CHECK: %[[BOX_ALLOCA:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf64>>>
   ! CHECK: %[[IVAR_ALLOCA:.*]] = fir.alloca i64 {bindc_name = "ivar", uniq_name = "_QFEivar"}
   ! CHECK: %[[IVAR_DECL_01:.*]]:2 = hlfir.declare %[[IVAR_ALLOCA]] {uniq_name = "_QFEivar"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
diff --git a/flang/test/Semantics/declarations08.f90 b/flang/test/Semantics/declarations08.f90
index bd14131b33c28..140ff710228c1 100644
--- a/flang/test/Semantics/declarations08.f90
+++ b/flang/test/Semantics/declarations08.f90
@@ -5,4 +5,10 @@
 !ERROR: Cray pointee 'x' may not be a member of a COMMON block
 common x
 equivalence(y,z)
+!ERROR: Cray pointee 'v' may not be initialized
+real :: v = 42.0
+pointer(p,v)
+!ERROR: Cray pointee 'u' may not be SAVE
+save u
+pointer(p, u)
 end

@akuhlens akuhlens requested a review from klausler April 24, 2025 21:56
@akuhlens akuhlens requested a review from klausler April 29, 2025 22:40
@akuhlens akuhlens merged commit a18adb2 into llvm:main May 2, 2025
11 checks passed
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…itialization (llvm#136776)

This PR:
- makes Cray pointer declarations shadow previous bindings instead of
modifying them,
- errors when the pointee of a cray pointee has the SAVE attribute, and
- adds a missing newline after dumping the list of cray pointers in a
scope.

Closes llvm#135579
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
…itialization (llvm#136776)

This PR:
- makes Cray pointer declarations shadow previous bindings instead of
modifying them,
- errors when the pointee of a cray pointee has the SAVE attribute, and
- adds a missing newline after dumping the list of cray pointers in a
scope.

Closes llvm#135579
@akuhlens akuhlens deleted the issue-135579 branch June 10, 2025 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang:openmp flang:semantics flang Flang issues not falling into any other category

Projects

None yet

3 participants