[flang-commits] [flang] a4bea99 - [flang] Add warning when BOZ literal is too large for assignment (#210749)
via flang-commits
flang-commits at lists.llvm.org
Fri Aug 14 04:36:41 PDT 2026
Author: John Otken
Date: 2026-08-14T07:36:35-04:00
New Revision: a4bea9975fbe73b02dfeffe896695494e1c19df9
URL: https://github.com/llvm/llvm-project/commit/a4bea9975fbe73b02dfeffe896695494e1c19df9
DIFF: https://github.com/llvm/llvm-project/commit/a4bea9975fbe73b02dfeffe896695494e1c19df9.diff
LOG: [flang] Add warning when BOZ literal is too large for assignment (#210749)
Generate a warning when a BOZ literal assignment does not fit into the
left-hand side 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
---------
Co-authored-by: John Otken <john.otken at hpe.com>
Added:
flang/test/Semantics/boz-truncation.f90
Modified:
flang/docs/Extensions.md
flang/include/flang/Support/Fortran-features.h
flang/lib/Semantics/expression.cpp
flang/lib/Support/Fortran-features.cpp
Removed:
################################################################################
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 36977e3f6df00..65ecd21bf71c9 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/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..766198c87945b 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; truncated"_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..4c4b064a17c60
--- /dev/null
+++ b/flang/test/Semantics/boz-truncation.f90
@@ -0,0 +1,26 @@
+! 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
+ i4 = z'0000000FFFFFFFF' ! long BOZ string with non-overflowing value
+ !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; 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; 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; truncated [-Wboz-literal-truncation]
+ u4 = z'1FFFFFFFF' ! 33 bits, too large for UNSIGNED(4)
+end program
More information about the flang-commits
mailing list