[flang-commits] [flang] [flang] Fix incorrect offset for zero-size COMMON block members. (PR #214174)

Daniel Chen via flang-commits flang-commits at lists.llvm.org
Thu Aug 6 08:52:19 PDT 2026


https://github.com/DanielCChen updated https://github.com/llvm/llvm-project/pull/214174

>From 0f68b553de950a60801cd744507e3a0ef5a96e80 Mon Sep 17 00:00:00 2001
From: Daniel Chen <cdchen at ca.ibm.com>
Date: Wed, 5 Aug 2026 05:42:47 -0400
Subject: [PATCH 1/5] [flang] Fix incorrect offset for zero-size COMMON block
 members.

---
 flang/lib/Semantics/compute-offsets.cpp |  6 +++++
 flang/test/Lower/common-block-char0.f90 | 36 +++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 flang/test/Lower/common-block-char0.f90

diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp
index e427586301dea..3a355f040b865 100644
--- a/flang/lib/Semantics/compute-offsets.cpp
+++ b/flang/lib/Semantics/compute-offsets.cpp
@@ -397,6 +397,12 @@ std::size_t ComputeOffsetsHelper::DoSymbol(
   }
   SizeAndAlignment s{GetSizeAndAlignment(symbol, true)};
   if (s.size == 0) {
+    // Zero-size symbols (e.g. CHARACTER*0) still occupy their sequential
+    // position in a COMMON block or derived-type sequence. Record the current
+    // offset so that LOC() and storage-association checks see the correct
+    // address rather than always returning the block base (offset 0).
+    symbol.set_size(0);
+    symbol.set_offset(offset_);
     return 0;
   }
   std::size_t previousOffset{offset_};
diff --git a/flang/test/Lower/common-block-char0.f90 b/flang/test/Lower/common-block-char0.f90
new file mode 100644
index 0000000000000..964d56f483f7c
--- /dev/null
+++ b/flang/test/Lower/common-block-char0.f90
@@ -0,0 +1,36 @@
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
+
+! Test that CHARACTER*0 symbols in a COMMON block are assigned their correct
+! sequential offset rather than always offset 0 (the block base address).
+!
+! Block /blk/ layout:
+!   offset  0 : ii1  (integer(8), 8 bytes)
+!   offset  8 : zc0  (character*0, 0 bytes)  <- zero-size, no storage consumed
+!   offset  8 : ll1  (integer(8), 8 bytes)
+!   Total: 16 bytes
+!
+! Before fix (compute-offsets.cpp): DoSymbol() returned early for zero-size
+! symbols without calling symbol.set_offset(), leaving zc0 stamped with
+! offset 0. This caused storage(%1[0]) for zc0 instead of storage(%1[8]).
+
+subroutine char0_common
+  integer(8) :: ii1
+  character*0 :: zc0
+  integer(8) :: ll1
+  common /blk/ ii1, zc0, ll1
+  call use(ii1, zc0, ll1)
+end subroutine
+
+! CHECK: fir.global common @blk_(dense<0> : vector<16xi8>) {alignment = 8 : i64} : !fir.array<16xi8>
+
+! CHECK-LABEL: func.func @_QPchar0_common
+
+! ii1 at offset 0
+! CHECK: %[[BASE:.*]] = fir.address_of(@blk_) : !fir.ref<!fir.array<16xi8>>
+! CHECK: hlfir.declare {{.*}} storage(%[[BASE]][0]) {uniq_name = "_QFchar0_commonEii1"}
+
+! ll1 at offset 8
+! CHECK: hlfir.declare {{.*}} storage(%[[BASE]][8]) {uniq_name = "_QFchar0_commonEll1"}
+
+! zc0 at offset 8 (not 0) -- key assertion
+! CHECK: hlfir.declare {{.*}} storage(%[[BASE]][8]) {uniq_name = "_QFchar0_commonEzc0"}

>From 00f437fdab973dd97e9d8e9e37134bc38d4c0aa1 Mon Sep 17 00:00:00 2001
From: Daniel Chen <cdchen at ca.ibm.com>
Date: Wed, 5 Aug 2026 19:54:54 -0400
Subject: [PATCH 2/5] To add another test to address review comment.

---
 flang/test/Lower/common-block-char0.f90 | 26 ++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/flang/test/Lower/common-block-char0.f90 b/flang/test/Lower/common-block-char0.f90
index 964d56f483f7c..d0bdc3f0d72c1 100644
--- a/flang/test/Lower/common-block-char0.f90
+++ b/flang/test/Lower/common-block-char0.f90
@@ -1,4 +1,4 @@
-! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
 
 ! Test that CHARACTER*0 symbols in a COMMON block are assigned their correct
 ! sequential offset rather than always offset 0 (the block base address).
@@ -34,3 +34,27 @@ subroutine char0_common
 
 ! zc0 at offset 8 (not 0) -- key assertion
 ! CHECK: hlfir.declare {{.*}} storage(%[[BASE]][8]) {uniq_name = "_QFchar0_commonEzc0"}
+
+! Test that a zero-size CHARACTER in a COMMON block does not trigger a false
+! "cannot backward-extend COMMON block" error when it is referenced in an
+! EQUIVALENCE association.
+!
+! Block /blk/ layout:
+!   offset  0 : i8   (integer(8), 8 bytes)
+!   offset  8 : zc0  (character(0), 0 bytes)
+!
+! equivalence (c8(5:8), zc0) places c8(1) at offset 4 (= 8 - 4 bytes before zc0).
+! Before the fix, zc0 had offset 0, so dep.offset (4) > symbol.offset() (0)
+! triggered the backward-extend error falsely.  After the fix, zc0.offset() == 8
+! so no backward extension occurs.
+!
+! CHECK-LABEL: func.func @_QPp09
+
+subroutine p09
+  integer(8) :: i8
+  character(0) :: zc0
+  character(8) :: c8
+  common /blk/ i8, zc0
+  equivalence (c8(5:8), zc0)
+  call use(c8, i8)
+end subroutine

>From 9f58299ee20d456f8dc17c30aa9b821c69ef518a Mon Sep 17 00:00:00 2001
From: Daniel Chen <cdchen at ca.ibm.com>
Date: Wed, 5 Aug 2026 23:36:09 -0400
Subject: [PATCH 3/5] To separate semantic testing from the lowering testing.

---
 flang/test/Lower/common-block-char0.f90     | 24 ---------------------
 flang/test/Semantics/common-block-char0.f90 | 23 ++++++++++++++++++++
 2 files changed, 23 insertions(+), 24 deletions(-)
 create mode 100644 flang/test/Semantics/common-block-char0.f90

diff --git a/flang/test/Lower/common-block-char0.f90 b/flang/test/Lower/common-block-char0.f90
index d0bdc3f0d72c1..02f2665d6faae 100644
--- a/flang/test/Lower/common-block-char0.f90
+++ b/flang/test/Lower/common-block-char0.f90
@@ -34,27 +34,3 @@ subroutine char0_common
 
 ! zc0 at offset 8 (not 0) -- key assertion
 ! CHECK: hlfir.declare {{.*}} storage(%[[BASE]][8]) {uniq_name = "_QFchar0_commonEzc0"}
-
-! Test that a zero-size CHARACTER in a COMMON block does not trigger a false
-! "cannot backward-extend COMMON block" error when it is referenced in an
-! EQUIVALENCE association.
-!
-! Block /blk/ layout:
-!   offset  0 : i8   (integer(8), 8 bytes)
-!   offset  8 : zc0  (character(0), 0 bytes)
-!
-! equivalence (c8(5:8), zc0) places c8(1) at offset 4 (= 8 - 4 bytes before zc0).
-! Before the fix, zc0 had offset 0, so dep.offset (4) > symbol.offset() (0)
-! triggered the backward-extend error falsely.  After the fix, zc0.offset() == 8
-! so no backward extension occurs.
-!
-! CHECK-LABEL: func.func @_QPp09
-
-subroutine p09
-  integer(8) :: i8
-  character(0) :: zc0
-  character(8) :: c8
-  common /blk/ i8, zc0
-  equivalence (c8(5:8), zc0)
-  call use(c8, i8)
-end subroutine
diff --git a/flang/test/Semantics/common-block-char0.f90 b/flang/test/Semantics/common-block-char0.f90
new file mode 100644
index 0000000000000..752f7a25d42e2
--- /dev/null
+++ b/flang/test/Semantics/common-block-char0.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Test that a zero-size CHARACTER in a COMMON block does not trigger a false
+! "cannot backward-extend COMMON block" error when it is referenced in an
+! EQUIVALENCE association.
+!
+! Block /blk/ layout:
+!   offset  0 : i8   (integer(8), 8 bytes)
+!   offset  8 : zc0  (character(0), 0 bytes)
+!
+! equivalence(c8(5:8), zc0) places c8(1) at offset 4 (= 8 - 4 bytes before zc0).
+! Before the fix (compute-offsets.cpp), zc0 had offset 0, so dep.offset (4)
+! > symbol.offset() (0) triggered the backward-extend error falsely.
+! After the fix, zc0.offset() == 8 so no backward extension occurs and no
+! error should be emitted.
+
+subroutine p09
+  integer(8) :: i8
+  character(0) :: zc0
+  character(8) :: c8
+  common /blk/ i8, zc0
+  equivalence (c8(5:8), zc0)
+  call use(c8, i8)
+end subroutine

>From 2d9597cc361c9c5672caf5ec1fbc33e97c59e9b7 Mon Sep 17 00:00:00 2001
From: Daniel Chen <cdchen at ca.ibm.com>
Date: Thu, 6 Aug 2026 00:34:41 -0400
Subject: [PATCH 4/5] Update the semantic test to address review comment.

---
 flang/test/Semantics/common-block-char0.f90 | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/flang/test/Semantics/common-block-char0.f90 b/flang/test/Semantics/common-block-char0.f90
index 752f7a25d42e2..85f3ff88ce9b7 100644
--- a/flang/test/Semantics/common-block-char0.f90
+++ b/flang/test/Semantics/common-block-char0.f90
@@ -21,3 +21,19 @@ subroutine p09
   equivalence (c8(5:8), zc0)
   call use(c8, i8)
 end subroutine
+
+! A genuine backward extension through a zero-size member must still error.
+! Block /blk2/ layout:
+!   offset  0 : zc0  (character(0), 0 bytes)
+!   offset  0 : i8   (integer(8), 8 bytes)
+!
+! equivalence(c8(5:8), zc0) would place c8(1) at offset -4 -- before the
+! block base -- which is a true backward extension and must be rejected.
+subroutine backward
+  integer(8) :: i8
+  character(0) :: zc0
+  character(8) :: c8
+  !ERROR: 'zc0' cannot backward-extend COMMON block /blk2/ via EQUIVALENCE with 'c8'
+  common /blk2/ zc0, i8
+  equivalence (c8(5:8), zc0)
+end subroutine

>From 0c449dd9f0542c642c8af6a1b9345605454026bc Mon Sep 17 00:00:00 2001
From: Daniel Chen <cdchen at ca.ibm.com>
Date: Thu, 6 Aug 2026 11:51:02 -0400
Subject: [PATCH 5/5] To address review comment to remove unnecessary
 descriptions in the test.

---
 flang/test/Semantics/common-block-char0.f90 | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/flang/test/Semantics/common-block-char0.f90 b/flang/test/Semantics/common-block-char0.f90
index 85f3ff88ce9b7..4210b28fb366e 100644
--- a/flang/test/Semantics/common-block-char0.f90
+++ b/flang/test/Semantics/common-block-char0.f90
@@ -8,10 +8,6 @@
 !   offset  8 : zc0  (character(0), 0 bytes)
 !
 ! equivalence(c8(5:8), zc0) places c8(1) at offset 4 (= 8 - 4 bytes before zc0).
-! Before the fix (compute-offsets.cpp), zc0 had offset 0, so dep.offset (4)
-! > symbol.offset() (0) triggered the backward-extend error falsely.
-! After the fix, zc0.offset() == 8 so no backward extension occurs and no
-! error should be emitted.
 
 subroutine p09
   integer(8) :: i8



More information about the flang-commits mailing list