[flang-commits] [flang] [flang] Diagnose ENUM BIND(C) value overflow (PR #224388)
J R Deva Dattan via flang-commits
flang-commits at lists.llvm.org
Fri Oct 9 02:10:54 PDT 2026
https://github.com/jrdevadattan updated https://github.com/llvm/llvm-project/pull/224388
>From 6b162df471458d527e2d19961eb73fcebd5ad292 Mon Sep 17 00:00:00 2001
From: jrdevadattan <jrdevadattan2006 at gmail.com>
Date: Fri, 18 Sep 2026 00:30:50 +0530
Subject: [PATCH 1/2] [flang] Diagnose ENUM BIND(C) value overflow
---
flang/lib/Semantics/resolve-names.cpp | 24 +++++++++++++++++++-----
flang/test/Semantics/resolve60.f90 | 6 ++++++
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 20a098d9f07321..03be486bad345f 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 56b1a7431f757a..8144d21c0d85c4 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
>From cebc13bf99e9482e6a5170ca6de19d455c8acffc Mon Sep 17 00:00:00 2001
From: J R Deva Dattan <jrdevadattan2006 at gmail.com>
Date: Fri, 9 Oct 2026 14:40:34 +0530
Subject: [PATCH 2/2] [flang] Apply clang-format to ENUM overflow diagnostic
---
flang/lib/Semantics/resolve-names.cpp | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5b5d3bc221fe29..62195cef491cfe 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6483,10 +6483,8 @@ 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()};
+ 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,
@@ -6545,8 +6543,8 @@ bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
if (symbol) {
if (enumerationState_.value) {
- symbol->get<ObjectEntityDetails>().set_init(SomeExpr{
- evaluate::Expr<evaluate::CInteger>{
+ symbol->get<ObjectEntityDetails>().set_init(
+ SomeExpr{evaluate::Expr<evaluate::CInteger>{
static_cast<evaluate::CInteger::Scalar>(
*enumerationState_.value)}});
} else {
More information about the flang-commits
mailing list