[flang-commits] [flang] d0caf0d - [flang] Avoid undefined behaviour when parsing format expressions (#147539)
via flang-commits
flang-commits at lists.llvm.org
Wed Jul 9 07:31:50 PDT 2025
Author: David Spickett
Date: 2025-07-09T15:31:45+01:00
New Revision: d0caf0d4857c2b00ba988f86703663685ec8697f
URL: https://github.com/llvm/llvm-project/commit/d0caf0d4857c2b00ba988f86703663685ec8697f
DIFF: https://github.com/llvm/llvm-project/commit/d0caf0d4857c2b00ba988f86703663685ec8697f.diff
LOG: [flang] Avoid undefined behaviour when parsing format expressions (#147539)
The test flang/test/Semantics/io08.f90 was failing when UBSAN was
enabled:
```
/home/david.spickett/llvm-project/flang/include/flang/Common/format.h:224:26: runtime error: signed integer overflow: 10 * 987654321098765432 cannot be represented in type 'int64_t' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/david.spickett/llvm-project/flang/include/flang/Common/format.h:224:26
```
This is because the code was effectively:
* Take the risk of UB happening
* Check whether it happened or not
Which UBSAN is obviously not going to like. Instead of checking after
the fact, use llvm's helpers that catch overflow without actually doing
it.
Added:
Modified:
flang/include/flang/Common/format.h
Removed:
################################################################################
diff --git a/flang/include/flang/Common/format.h b/flang/include/flang/Common/format.h
index 1650f56140b4d..11aa6f2c07797 100644
--- a/flang/include/flang/Common/format.h
+++ b/flang/include/flang/Common/format.h
@@ -11,6 +11,7 @@
#include "Fortran-consts.h"
#include "enum-set.h"
+#include "llvm/Support/MathExtras.h"
#include <cstring>
// Define a FormatValidator class template to validate a format expression
@@ -214,16 +215,18 @@ 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_) {
- overflow = true;
+ if (LLVM_LIKELY(!overflow)) {
+ overflow = llvm::MulOverflow(
+ static_cast<int64_t>(10), integerValue_, integerValue_);
+ }
+ if (LLVM_LIKELY(!overflow)) {
+ overflow = llvm::AddOverflow(
+ integerValue_, static_cast<int64_t>(c - '0'), integerValue_);
}
c = NextChar();
} while (c >= '0' && c <= '9');
More information about the flang-commits
mailing list