[flang-commits] [flang] [flang] Do not error on constant nonzero UB in substring of ZLA (PR #174511)
via flang-commits
flang-commits at lists.llvm.org
Wed Jan 7 13:54:03 PST 2026
https://github.com/tmjbios updated https://github.com/llvm/llvm-project/pull/174511
>From 84151a127eb6f8872fdb8d6bbc4f0be45935a271 Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedmjohnson at protonmail.com>
Date: Fri, 2 Jan 2026 21:09:18 +0000
Subject: [PATCH 1/2] Do not error on constant nonzero UB in substring of ZLA
A substring reference where the lower bound is higher
than the upper bound is defined in 9.4.1 to be zero-length.
Thus, a reference to a substring of a CHARACTER*(0)
string such as
string(foo():2)
cannot be a compile-time error since we do not know
the return value of foo().
We also should not error if the lbound > ubound at compile time.
---
flang/lib/Semantics/expression.cpp | 4 +--
flang/test/Semantics/zero_len_char_array.f90 | 30 ++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Semantics/zero_len_char_array.f90
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 402e88252fc20..89bc7264707de 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1221,9 +1221,9 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Substring &ss) {
Say("Substring must begin at 1 or later, not %jd"_err_en_US,
static_cast<std::intmax_t>(*lbValue));
return std::nullopt;
- } else if (ubValue && len && *ubValue > *len &&
+ } else if (ubValue && len && *len > 0 && *ubValue > *len &&
(lbValue || !first)) {
- Say("Substring must end at %zd or earlier, not %jd"_err_en_US,
+ Say("Substring must end at %jd or earlier, not %jd"_err_en_US,
static_cast<std::intmax_t>(*len),
static_cast<std::intmax_t>(*ubValue));
return std::nullopt;
diff --git a/flang/test/Semantics/zero_len_char_array.f90 b/flang/test/Semantics/zero_len_char_array.f90
new file mode 100644
index 0000000000000..ee9f10fdd6d67
--- /dev/null
+++ b/flang/test/Semantics/zero_len_char_array.f90
@@ -0,0 +1,30 @@
+! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
+! CHECK-NOT: error:
+! Test that zero-length character substrings with lbound>ubounds indices
+! do not produce spurious errors when the character array is zero length.
+
+integer function init(i)
+ integer i
+ init=i
+end
+
+program flang_t7052
+ character*(*), parameter :: param_char = ""
+ character*(0) :: zero_len_char
+
+ if ( param_char(init(5):init(3)) > zero_len_char(1:-2) ) then
+ print *,"Test failed"
+ endif
+
+ if ( param_char(init(5):init(3)) > zero_len_char(10:2) ) then
+ print *,"Test failed"
+ endif
+
+ if ( param_char(init(5):init(3)) > zero_len_char(init(10):2) ) then
+ print *,"Test failed"
+ endif
+
+ if ( param_char(init(5):init(3)) > zero_len_char(init(10):-2) ) then
+ print *,"Test failed"
+ endif
+end program
>From a674969dd53e055be0b0f4a07a85d9e7c7b57ae0 Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedmjohnson at protonmail.com>
Date: Wed, 7 Jan 2026 12:31:10 -0600
Subject: [PATCH 2/2] Updates based on feedback
* Cleaned up the test
* Moved the zero-len check to the empty array check condition
* Ran "Fortran" llvm-test-suite in addition to check-flang
---
flang/lib/Semantics/expression.cpp | 5 +++--
flang/test/Semantics/zero_len_char_array.f90 | 19 +++++++++++++------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 89bc7264707de..7e033a0c0fc4a 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1215,13 +1215,14 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Substring &ss) {
if (!ubValue) {
ubValue = len;
}
- if (lbValue && ubValue && *lbValue > *ubValue) {
+ if ((len && *len == 0) ||
+ (lbValue && ubValue && *lbValue > *ubValue)) {
// valid, substring is empty
} else if (lbValue && *lbValue < 1 && (ubValue || !last)) {
Say("Substring must begin at 1 or later, not %jd"_err_en_US,
static_cast<std::intmax_t>(*lbValue));
return std::nullopt;
- } else if (ubValue && len && *len > 0 && *ubValue > *len &&
+ } else if (ubValue && len && *ubValue > *len &&
(lbValue || !first)) {
Say("Substring must end at %jd or earlier, not %jd"_err_en_US,
static_cast<std::intmax_t>(*len),
diff --git a/flang/test/Semantics/zero_len_char_array.f90 b/flang/test/Semantics/zero_len_char_array.f90
index ee9f10fdd6d67..3998cd32c818c 100644
--- a/flang/test/Semantics/zero_len_char_array.f90
+++ b/flang/test/Semantics/zero_len_char_array.f90
@@ -2,13 +2,8 @@
! CHECK-NOT: error:
! Test that zero-length character substrings with lbound>ubounds indices
! do not produce spurious errors when the character array is zero length.
-
-integer function init(i)
- integer i
- init=i
-end
-
program flang_t7052
+ implicit none
character*(*), parameter :: param_char = ""
character*(0) :: zero_len_char
@@ -27,4 +22,16 @@ program flang_t7052
if ( param_char(init(5):init(3)) > zero_len_char(init(10):-2) ) then
print *,"Test failed"
endif
+
+ if ( param_char(init(5):init(3)) > zero_len_char(2:init(10)) ) then
+ print *,"Test failed"
+ endif
+
+contains
+
+ integer function init(i)
+ integer, intent(in) :: i
+ init=i
+ end
+
end program
More information about the flang-commits
mailing list