[flang-commits] [flang] [flang] Add warning when BOZ literal is too large for assignment (PR #210749)

John Otken via flang-commits flang-commits at lists.llvm.org
Thu Aug 13 16:58:12 PDT 2026


https://github.com/jotken updated https://github.com/llvm/llvm-project/pull/210749

>From 0b8fb1bafb8720c9433453a096591f958a31a575 Mon Sep 17 00:00:00 2001
From: John Otken <john at otken.com>
Date: Mon, 20 Jul 2026 10:52:30 -0500
Subject: [PATCH 1/4] [flang] Add warning when BOZ literal is too large for
 assignment

Generate a warning when a BOZ literal assignment does not fit into the lhs variable.

AI use disclaimer: Github CoPilot assisted with this PR. I manually reviewed and tested the code.

Co-authored-by: John Otken john.otken at hpe.com
---
 .../include/flang/Support/Fortran-features.h  |  3 ++-
 flang/lib/Semantics/expression.cpp            | 11 ++++++++
 flang/lib/Support/Fortran-features.cpp        |  1 +
 flang/test/Semantics/boz-truncation.f90       | 25 +++++++++++++++++++
 4 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Semantics/boz-truncation.f90

diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index 9bbbb7dd5f899..4ee956a0b4a4f 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -87,7 +87,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
     RealConstantWidening, VolatileOrAsynchronousTemporary, UnusedVariable,
     UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy,
     MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure,
-    IgnoredNoReallocateLHS, ExperimentalOption, IoImpliedDoIndexConflict)
+    IgnoredNoReallocateLHS, ExperimentalOption, IoImpliedDoIndexConflict,
+    BOZLiteralTruncation)
 
 using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
 using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index fc57cc43e981c..d185b94eaf9da 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -5875,6 +5875,17 @@ void ArgumentAnalyzer::ConvertBOZAssignmentRHS(const DynamicType &lhsType) {
       lhsType.category() == TypeCategory::Unsigned ||
       lhsType.category() == TypeCategory::Real) {
     Expr<SomeType> rhs{MoveExpr(1)};
+    if (lhsType.category() == TypeCategory::Integer ||
+        lhsType.category() == TypeCategory::Unsigned) {
+      if (const auto *boz{std::get_if<BOZLiteralConstant>(&rhs.u)};
+          boz && boz->bits - boz->LEADZ() > lhsType.kind() * 8) {
+        context_.Warn(common::UsageWarning::BOZLiteralTruncation,
+            "BOZ literal constant is too large for %s(KIND=%d) assignment target"_warn_en_US,
+            lhsType.category() == TypeCategory::Unsigned ? "UNSIGNED"
+                                                         : "INTEGER",
+            lhsType.kind());
+      }
+    }
     if (MaybeExpr converted{ConvertToType(lhsType, std::move(rhs))}) {
       actuals_[1] = std::move(*converted);
     }
diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp
index d94729200df06..0af3ff61d18e1 100644
--- a/flang/lib/Support/Fortran-features.cpp
+++ b/flang/lib/Support/Fortran-features.cpp
@@ -222,6 +222,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
   warnUsage_.set(UsageWarning::ImpureFinalInPure);
   warnUsage_.set(UsageWarning::IgnoredNoReallocateLHS);
   warnUsage_.set(UsageWarning::IoImpliedDoIndexConflict);
+  warnUsage_.set(UsageWarning::BOZLiteralTruncation);
   warnLanguage_.set(LanguageFeature::OpenMPThreadprivateEquivalence);
   warnLanguage_.set(LanguageFeature::OpenAccDefaultNoneScalarsStrict);
   warnLanguage_.set(LanguageFeature::OpenACCMultipleNamesInRoutine);
diff --git a/flang/test/Semantics/boz-truncation.f90 b/flang/test/Semantics/boz-truncation.f90
new file mode 100644
index 0000000000000..8a337ac92849e
--- /dev/null
+++ b/flang/test/Semantics/boz-truncation.f90
@@ -0,0 +1,25 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -funsigned -Werror
+! Test the warning for a BOZ literal constant that is too large for the
+! INTEGER or UNSIGNED type of an assignment target.
+program boztest
+  integer(4) :: i4
+  integer(8) :: i8
+  unsigned(2) :: u2
+  unsigned(4) :: u4
+
+  ! INTEGER targets
+  i4 = z'FFFFFFFF' ! fits in 32 bits, no warning
+  !WARNING: BOZ literal constant is too large for INTEGER(KIND=4) assignment target [-Wboz-literal-truncation]
+  i4 = z'1FFFFFFFF' ! 33 bits, too large for INTEGER(4)
+  i8 = z'FFFFFFFFFFFFFFFF' ! fits in 64 bits, no warning
+  !WARNING: BOZ literal constant is too large for INTEGER(KIND=8) assignment target [-Wboz-literal-truncation]
+  i8 = z'1FFFFFFFFFFFFFFFF' ! 65 bits, too large for INTEGER(8)
+
+  ! UNSIGNED targets
+  u2 = z'FFFF' ! fits in 16 bits, no warning
+  !WARNING: BOZ literal constant is too large for UNSIGNED(KIND=2) assignment target [-Wboz-literal-truncation]
+  u2 = z'1FFFF' ! 17 bits, too large for UNSIGNED(2)
+  u4 = z'FFFFFFFF' ! fits in 32 bits, no warning
+  !WARNING: BOZ literal constant is too large for UNSIGNED(KIND=4) assignment target [-Wboz-literal-truncation]
+  u4 = z'1FFFFFFFF' ! 33 bits, too large for UNSIGNED(4)
+end program

>From d79a2cccad58d6759c494cd07e9e4982610d244d Mon Sep 17 00:00:00 2001
From: John Otken <john.otken at hpe.com>
Date: Wed, 22 Jul 2026 11:13:55 -0500
Subject: [PATCH 2/4] Restart CI Checks


>From 6296177b4a197e6ead2928cb080f45fab2580e66 Mon Sep 17 00:00:00 2001
From: John Otken <john.otken at hpe.com>
Date: Thu, 13 Aug 2026 17:10:32 -0500
Subject: [PATCH 3/4] Add note to Extensions, update warning message, add test
 case for non-overflowing BOZ string.

---
 flang/docs/Extensions.md                | 1 +
 flang/lib/Semantics/expression.cpp      | 2 +-
 flang/test/Semantics/boz-truncation.f90 | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 054e38c623bca..58595e4e466aa 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -294,6 +294,7 @@ end
   not be known (e.g., `IAND(X'1',X'2')`, or as arguments of `DIM`, `MOD`,
   `MODULO`, and `SIGN`. Note that while other compilers may accept such usages,
   the type resolution of such BOZ literals usages is highly non portable).
+  A warning is emitted when the BOZ literal is too large for the target.
 * BOZ literals can also be used as REAL values in some contexts where the
   type is unambiguous, such as initializations of REAL parameters.
 * `TRANSFER(boz, MOLD=integer or real scalar)` is accepted as an alternate
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index d185b94eaf9da..766198c87945b 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -5880,7 +5880,7 @@ void ArgumentAnalyzer::ConvertBOZAssignmentRHS(const DynamicType &lhsType) {
       if (const auto *boz{std::get_if<BOZLiteralConstant>(&rhs.u)};
           boz && boz->bits - boz->LEADZ() > lhsType.kind() * 8) {
         context_.Warn(common::UsageWarning::BOZLiteralTruncation,
-            "BOZ literal constant is too large for %s(KIND=%d) assignment target"_warn_en_US,
+            "BOZ literal constant is too large for %s(KIND=%d) assignment target; truncated"_warn_en_US,
             lhsType.category() == TypeCategory::Unsigned ? "UNSIGNED"
                                                          : "INTEGER",
             lhsType.kind());
diff --git a/flang/test/Semantics/boz-truncation.f90 b/flang/test/Semantics/boz-truncation.f90
index 8a337ac92849e..69f096f5f3007 100644
--- a/flang/test/Semantics/boz-truncation.f90
+++ b/flang/test/Semantics/boz-truncation.f90
@@ -9,6 +9,7 @@ program boztest
 
   ! INTEGER targets
   i4 = z'FFFFFFFF' ! fits in 32 bits, no warning
+  i4 = z'0000000FFFFFFFF' ! long BOZ string with non-overflowing value
   !WARNING: BOZ literal constant is too large for INTEGER(KIND=4) assignment target [-Wboz-literal-truncation]
   i4 = z'1FFFFFFFF' ! 33 bits, too large for INTEGER(4)
   i8 = z'FFFFFFFFFFFFFFFF' ! fits in 64 bits, no warning

>From c6cabb6a957ad0a7e2a479277f78cbbffd1d4e7e Mon Sep 17 00:00:00 2001
From: John Otken <john.otken at hpe.com>
Date: Thu, 13 Aug 2026 18:57:09 -0500
Subject: [PATCH 4/4] Add "; truncated" to WARNING text in unit test.

---
 flang/test/Semantics/boz-truncation.f90 | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/flang/test/Semantics/boz-truncation.f90 b/flang/test/Semantics/boz-truncation.f90
index 69f096f5f3007..4c4b064a17c60 100644
--- a/flang/test/Semantics/boz-truncation.f90
+++ b/flang/test/Semantics/boz-truncation.f90
@@ -10,17 +10,17 @@ program boztest
   ! INTEGER targets
   i4 = z'FFFFFFFF' ! fits in 32 bits, no warning
   i4 = z'0000000FFFFFFFF' ! long BOZ string with non-overflowing value
-  !WARNING: BOZ literal constant is too large for INTEGER(KIND=4) assignment target [-Wboz-literal-truncation]
+  !WARNING: BOZ literal constant is too large for INTEGER(KIND=4) assignment target; truncated [-Wboz-literal-truncation]
   i4 = z'1FFFFFFFF' ! 33 bits, too large for INTEGER(4)
   i8 = z'FFFFFFFFFFFFFFFF' ! fits in 64 bits, no warning
-  !WARNING: BOZ literal constant is too large for INTEGER(KIND=8) assignment target [-Wboz-literal-truncation]
+  !WARNING: BOZ literal constant is too large for INTEGER(KIND=8) assignment target; truncated [-Wboz-literal-truncation]
   i8 = z'1FFFFFFFFFFFFFFFF' ! 65 bits, too large for INTEGER(8)
 
   ! UNSIGNED targets
   u2 = z'FFFF' ! fits in 16 bits, no warning
-  !WARNING: BOZ literal constant is too large for UNSIGNED(KIND=2) assignment target [-Wboz-literal-truncation]
+  !WARNING: BOZ literal constant is too large for UNSIGNED(KIND=2) assignment target; truncated [-Wboz-literal-truncation]
   u2 = z'1FFFF' ! 17 bits, too large for UNSIGNED(2)
   u4 = z'FFFFFFFF' ! fits in 32 bits, no warning
-  !WARNING: BOZ literal constant is too large for UNSIGNED(KIND=4) assignment target [-Wboz-literal-truncation]
+  !WARNING: BOZ literal constant is too large for UNSIGNED(KIND=4) assignment target; truncated [-Wboz-literal-truncation]
   u4 = z'1FFFFFFFF' ! 33 bits, too large for UNSIGNED(4)
 end program



More information about the flang-commits mailing list