[flang-commits] [flang] [flang] Diagnose ENUM BIND(C) value overflow (PR #224388)
via flang-commits
flang-commits at lists.llvm.org
Thu Sep 17 12:26:22 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: J R Deva Dattan (jrdevadattan)
<details>
<summary>Changes</summary>
Title:
[flang] Diagnose ENUM BIND(C) value overflow
Summary:
- Keep the pending `ENUM, BIND(C)` enumerator value in `int64_t` while resolving enumerators.
- Diagnose values outside the `INTEGER(4)` / `C_INT` range before constructing the Flang integer value.
- Add a regression test for an implicit enumerator following `huge(0_4)`.
Fixes #<!-- -->224036
---
Full diff: https://github.com/llvm/llvm-project/pull/224388.diff
2 Files Affected:
- (modified) flang/lib/Semantics/resolve-names.cpp (+19-5)
- (modified) flang/test/Semantics/resolve60.f90 (+6)
``````````diff
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 20a098d9f0732..03be486bad345 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -46,6 +46,8 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <limits>
#include <list>
#include <map>
#include <set>
@@ -1315,7 +1317,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
// Info about current ENUM
struct EnumeratorState {
// Enum value must hold inside a C_INT (7.6.2).
- std::optional<int> value{0};
+ std::optional<std::int64_t> value{0};
} enumerationState_;
// Set for OldParameterStmt processing
bool inOldStyleParameterStmt_{false};
@@ -6382,6 +6384,10 @@ bool DeclarationVisitor::Pre(const parser::NamedConstant &x) {
bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
const parser::Name &name{std::get<parser::NamedConstant>(enumerator.t).v};
+ constexpr std::int64_t minCInt{
+ std::numeric_limits<std::int32_t>::min()};
+ constexpr std::int64_t maxCInt{
+ std::numeric_limits<std::int32_t>::max()};
Symbol *symbol{FindInScope(name)};
if (symbol && !symbol->has<UnknownDetails>()) {
// Contrary to named constants appearing in a PARAMETER statement,
@@ -6420,9 +6426,7 @@ bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
value = EvaluateInt64(context(), *init);
}
if (value) {
- // Cast all init expressions to C_INT so that they can then be
- // safely incremented (see 7.6 Note 2).
- enumerationState_.value = static_cast<int>(*value);
+ enumerationState_.value = *value;
} else {
Say(name,
"Enumerator value could not be computed "
@@ -6432,10 +6436,20 @@ bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
}
}
+ if (enumerationState_.value &&
+ (*enumerationState_.value < minCInt ||
+ *enumerationState_.value > maxCInt)) {
+ Say(name, "Enumerator value is out of range for INTEGER(%d)"_err_en_US,
+ evaluate::CInteger::kind);
+ enumerationState_.value = std::nullopt;
+ }
+
if (symbol) {
if (enumerationState_.value) {
symbol->get<ObjectEntityDetails>().set_init(SomeExpr{
- evaluate::Expr<evaluate::CInteger>{*enumerationState_.value}});
+ evaluate::Expr<evaluate::CInteger>{
+ static_cast<evaluate::CInteger::Scalar>(
+ *enumerationState_.value)}});
} else {
context().SetError(*symbol);
}
diff --git a/flang/test/Semantics/resolve60.f90 b/flang/test/Semantics/resolve60.f90
index 56b1a7431f757..8144d21c0d85c 100644
--- a/flang/test/Semantics/resolve60.f90
+++ b/flang/test/Semantics/resolve60.f90
@@ -43,4 +43,10 @@
enumerator :: wrong = 0/0
end enum
+ enum, bind(C)
+ enumerator :: max = huge(0_4)
+ !ERROR: Enumerator value is out of range for INTEGER(4)
+ enumerator :: too_large
+ end enum
+
end
``````````
</details>
https://github.com/llvm/llvm-project/pull/224388
More information about the flang-commits
mailing list