[flang-commits] [flang] [flang][OpenMP] Add diagnostic for ATOMIC WRITE with pointer to non-intrinsic type (PR #162364)

Krish Gupta via flang-commits flang-commits at lists.llvm.org
Tue Oct 7 13:16:36 PDT 2025


https://github.com/KrxGu created https://github.com/llvm/llvm-project/pull/162364

Fixes #161932

### Problem
When using `!$omp atomic write` with a POINTER variable to a derived type in intrinsic assignment, Flang would crash with a FIR verifier error instead of providing a clear semantic diagnostic.

**Example that previously crashed:**
```fortran
module p
    type t
    end type
    contains
    subroutine s(a1, a2)
        type(t), pointer :: a1, a2
        !$omp atomic write
        a1 = a2  ! Crashed with FIR verifier error
    end subroutine
end module
```
Solution
Added a semantic check in [CheckAtomicWriteAssignment()](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) that detects when:

The assignment is an intrinsic assignment (not pointer assignment =>)
The variable has the POINTER attribute
The pointee type is non-intrinsic (derived type, character, etc.)
The check now emits a clear error message before reaching the FIR stage:
```error: ATOMIC WRITE requires an intrinsic scalar variable; 'a1' has the POINTER attribute and derived type 't'```

<img width="1234" height="214" alt="image" src="https://github.com/user-attachments/assets/1067148f-3734-4a39-913b-df37f0e38b0f" />

What remains valid
According to OpenMP 6.0 spec, the following cases are still allowed:

✅ integer, pointer :: p; p = 5 — pointer to intrinsic type with intrinsic assignment
✅ integer, pointer :: p, q; p => q — pointer assignment
✅ [type(t), pointer :: a, b; a => b](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) — pointer assignment with derived type
What is now rejected
❌ [type(t), pointer :: a, b; a = b](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) — intrinsic assignment where the dereferenced value is non-intrinsic

Testing
All existing atomic tests pass (15/15)
New test validates the error diagnostic
Verified the original crash scenario now produces a clear error instead

<img width="1180" height="364" alt="image" src="https://github.com/user-attachments/assets/3740f431-cd1a-4cb9-b58c-ad97f17fa52c" />


>From a6d387e265f497f680634f99b365bee9cf9ff33f Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Tue, 7 Oct 2025 12:55:14 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add test: named COMMON + member with
 firstprivate+lastprivate is valid

---
 flang/test/Semantics/OpenMP/omp-common-fp-lp.f90 | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 flang/test/Semantics/OpenMP/omp-common-fp-lp.f90

diff --git a/flang/test/Semantics/OpenMP/omp-common-fp-lp.f90 b/flang/test/Semantics/OpenMP/omp-common-fp-lp.f90
new file mode 100644
index 0000000000000..3d6ba1547a09e
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/omp-common-fp-lp.f90
@@ -0,0 +1,13 @@
+! RUN: %flang_fc1 -fopenmp -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty
+! CHECK-NOT: error:
+! CHECK-NOT: warning:
+
+subroutine sub1()
+  common /com/ j
+  j = 10
+!$omp parallel do firstprivate(j) lastprivate(/com/)
+  do i = 1, 10
+     j = j + 1
+  end do
+!$omp end parallel do
+end

>From fc9683e8f38eb53a700be7143824ca7d70a82201 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Wed, 8 Oct 2025 01:39:02 +0530
Subject: [PATCH 2/2] [flang][OpenMP] Add diagnostic for ATOMIC WRITE with
 pointer to non-intrinsic type

Fixes #161932
---
 flang/lib/Semantics/check-omp-atomic.cpp      | 26 ++++++++++++++++++-
 .../omp-atomic-write-pointer-derived.f90      |  8 ++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Semantics/OpenMP/omp-atomic-write-pointer-derived.f90

diff --git a/flang/lib/Semantics/check-omp-atomic.cpp b/flang/lib/Semantics/check-omp-atomic.cpp
index 351af5c099aee..00c6a2d2b5fe3 100644
--- a/flang/lib/Semantics/check-omp-atomic.cpp
+++ b/flang/lib/Semantics/check-omp-atomic.cpp
@@ -539,7 +539,6 @@ void OmpStructureChecker::CheckAtomicType(
     return;
   }
 
-  // Variable is a pointer.
   if (typeSpec->IsPolymorphic()) {
     context_.Say(source,
         "Atomic variable %s cannot be a pointer to a polymorphic type"_err_en_US,
@@ -829,6 +828,31 @@ void OmpStructureChecker::CheckAtomicWriteAssignment(
   if (!IsVarOrFunctionRef(atom)) {
     ErrorShouldBeVariable(atom, rsrc);
   } else {
+    // For intrinsic assignment (x = expr), check if the variable is a pointer
+    // to a non-intrinsic type, which is not allowed in ATOMIC WRITE
+    if (!IsPointerAssignment(write)) {
+      std::vector<SomeExpr> dsgs{GetAllDesignators(atom)};
+      if (!dsgs.empty()) {
+        evaluate::SymbolVector syms{evaluate::GetSymbolVector(dsgs.front())};
+        if (!syms.empty() && IsPointer(syms.back())) {
+          SymbolRef sym = syms.back();
+          if (const DeclTypeSpec *typeSpec{sym->GetType()}) {
+            using Category = DeclTypeSpec::Category;
+            Category cat{typeSpec->category()};
+            if (cat != Category::Numeric && cat != Category::Logical) {
+              std::string details = " has the POINTER attribute";
+              if (const auto *derived{typeSpec->AsDerived()}) {
+                details += " and derived type '"s + derived->name().ToString() + "'";
+              }
+              context_.Say(lsrc,
+                  "ATOMIC WRITE requires an intrinsic scalar variable; '%s'%s"_err_en_US,
+                  sym->name(), details);
+              return;
+            }
+          }
+        }
+      }
+    }
     CheckAtomicVariable(atom, lsrc);
     CheckStorageOverlap(atom, {write.rhs}, source);
   }
diff --git a/flang/test/Semantics/OpenMP/omp-atomic-write-pointer-derived.f90 b/flang/test/Semantics/OpenMP/omp-atomic-write-pointer-derived.f90
new file mode 100644
index 0000000000000..d1ca2308047ad
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/omp-atomic-write-pointer-derived.f90
@@ -0,0 +1,8 @@
+! RUN: not %flang_fc1 -fopenmp -fsyntax-only %s 2>&1 | FileCheck %s
+type t
+end type
+type(t), pointer :: a1, a2
+!$omp atomic write
+a1 = a2
+! CHECK: error: ATOMIC WRITE requires an intrinsic scalar variable; 'a1' has the POINTER attribute and derived type 't'
+end



More information about the flang-commits mailing list