[flang-commits] [flang] [flang][runtime] Fix integer overflow check in FORMAT (PR #79368)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Wed Jan 24 15:07:52 PST 2024
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/79368
>From 7b222da489dfbe88d2175daad4e48c2f70671d17 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 24 Jan 2024 12:52:25 -0800
Subject: [PATCH] [flang][runtime] Fix integer overflow check in FORMAT
The integer overflow check used for repeat counts &c. in FORMAT
specifications was incorrect; fix it.
Fixes https://github.com/llvm/llvm-project/issues/79255.
---
flang/include/flang/Common/format.h | 5 ++---
flang/runtime/format-implementation.h | 9 ++++-----
flang/test/Semantics/io08.f90 | 2 +-
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/flang/include/flang/Common/format.h b/flang/include/flang/Common/format.h
index 2374ff6983cf41..9bb3f708edaa38 100644
--- a/flang/include/flang/Common/format.h
+++ b/flang/include/flang/Common/format.h
@@ -12,6 +12,7 @@
#include "enum-set.h"
#include "flang/Common/Fortran.h"
#include <cstring>
+#include <limits>
// Define a FormatValidator class template to validate a format expression
// of a given CHAR type. To enable use in runtime library code as well as
@@ -214,15 +215,13 @@ template <typename CHAR> void FormatValidator<CHAR>::NextToken() {
case '7':
case '8':
case '9': {
- int64_t lastValue;
const CHAR *lastCursor;
integerValue_ = 0;
bool overflow{false};
do {
- lastValue = integerValue_;
lastCursor = cursor_;
integerValue_ = 10 * integerValue_ + c - '0';
- if (lastValue > integerValue_) {
+ if (integerValue_ > std::numeric_limits<int>::max()) {
overflow = true;
}
c = NextChar();
diff --git a/flang/runtime/format-implementation.h b/flang/runtime/format-implementation.h
index c54ac062c7beab..0bad3c735cc24e 100644
--- a/flang/runtime/format-implementation.h
+++ b/flang/runtime/format-implementation.h
@@ -63,7 +63,7 @@ FormatControl<CONTEXT>::FormatControl(const Terminator &terminator,
}
template <typename CONTEXT>
-int FormatControl<CONTEXT>::GetIntField(
+std::int32_t FormatControl<CONTEXT>::GetIntField(
IoErrorHandler &handler, CharType firstCh, bool *hadError) {
CharType ch{firstCh ? firstCh : PeekNext()};
if (ch != '-' && ch != '+' && (ch < '0' || ch > '9')) {
@@ -74,7 +74,7 @@ int FormatControl<CONTEXT>::GetIntField(
}
return 0;
}
- int result{0};
+ std::int64_t result{0};
bool negate{ch == '-'};
if (negate || ch == '+') {
if (firstCh) {
@@ -85,8 +85,8 @@ int FormatControl<CONTEXT>::GetIntField(
ch = PeekNext();
}
while (ch >= '0' && ch <= '9') {
- if (result >
- std::numeric_limits<int>::max() / 10 - (static_cast<int>(ch) - '0')) {
+ result = 10 * result + ch - '0';
+ if (result > std::numeric_limits<int>::max()) {
handler.SignalError(
IostatErrorInFormat, "FORMAT integer field out of range");
if (hadError) {
@@ -94,7 +94,6 @@ int FormatControl<CONTEXT>::GetIntField(
}
return result;
}
- result = 10 * result + ch - '0';
if (firstCh) {
firstCh = '\0';
} else {
diff --git a/flang/test/Semantics/io08.f90 b/flang/test/Semantics/io08.f90
index f6038b471759f3..b1685e754192f3 100644
--- a/flang/test/Semantics/io08.f90
+++ b/flang/test/Semantics/io08.f90
@@ -36,7 +36,7 @@
write(*,'("a""""bc", 2x)')
write(*,'(3Habc)')
write(*,'(3Habc, 2X, 3X)')
- write(*,'(987654321098765432X)')
+ write(*,'(2147483647X)')
write(*,'($)')
write(*,'(\)')
write(*,'(RZ,RU,RP,RN,RD,RC,SS,SP,S,3G15.3e2)')
More information about the flang-commits
mailing list