[flang-commits] [flang] fcec9ce - [flang] Do not error on constant nonzero UB in substring of ZLA (#174511)

via flang-commits flang-commits at lists.llvm.org
Thu Jan 8 10:28:52 PST 2026


Author: TMJ
Date: 2026-01-08T13:28:48-05:00
New Revision: fcec9ced47c5b1e2479fa86f7b51a73ba6feb3f7

URL: https://github.com/llvm/llvm-project/commit/fcec9ced47c5b1e2479fa86f7b51a73ba6feb3f7
DIFF: https://github.com/llvm/llvm-project/commit/fcec9ced47c5b1e2479fa86f7b51a73ba6feb3f7.diff

LOG: [flang] Do not error on constant nonzero UB in substring of ZLA (#174511)

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.

Added: 
    flang/test/Semantics/zero_len_char_array.f90

Modified: 
    flang/lib/Semantics/expression.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index fd0a16f19ccc4..6e301e6ba752a 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1215,7 +1215,8 @@ 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,
@@ -1223,7 +1224,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Substring &ss) {
                 return std::nullopt;
               } else if (ubValue && len && *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..3998cd32c818c
--- /dev/null
+++ b/flang/test/Semantics/zero_len_char_array.f90
@@ -0,0 +1,37 @@
+! 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.
+program flang_t7052
+  implicit none
+  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
+
+  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