[llvm] [flang][runtime] Better handling for integer input into null address (PR #135987)

Peter Klausler via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 16 09:51:36 PDT 2025


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/135987

The original descriptor-only path for I/O checks for null data addresses and crashes with a readable message, but there's no such check on the new fast path for formatted integer input, and so a READ into (say) a deallocated allocatable will crash with a segfault.  Put a null data address check on the new fast path.

>From 116be4545f8640cd69f8cccbd7e28f837c446039 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 16 Apr 2025 09:48:15 -0700
Subject: [PATCH] [flang][runtime] Better handling for integer input into null
 address

The original descriptor-only path for I/O checks for null data addresses
and crashes with a readable message, but there's no such check on the
new fast path for formatted integer input, and so a READ into (say) a
deallocated allocatable will crash with a segfault.  Put a null data
address check on the new fast path.
---
 flang-rt/lib/runtime/edit-input.cpp | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/flang-rt/lib/runtime/edit-input.cpp b/flang-rt/lib/runtime/edit-input.cpp
index 4aa8c70f776cd..dfb8d71298dc1 100644
--- a/flang-rt/lib/runtime/edit-input.cpp
+++ b/flang-rt/lib/runtime/edit-input.cpp
@@ -188,7 +188,11 @@ static RT_API_ATTRS char ScanNumericPrefix(IoStatementState &io,
 
 RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
     void *n, int kind, bool isSigned) {
-  RUNTIME_CHECK(io.GetIoErrorHandler(), kind >= 1 && !(kind & (kind - 1)));
+  auto &handler{io.GetIoErrorHandler()};
+  RUNTIME_CHECK(handler, kind >= 1 && !(kind & (kind - 1)));
+  if (!n) {
+    io.GetIoErrorHandler().Crash("Null address for integer input item");
+  }
   switch (edit.descriptor) {
   case DataEdit::ListDirected:
     if (IsNamelistNameOrSlash(io)) {
@@ -207,7 +211,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
   case 'A': // legacy extension
     return EditCharacterInput(io, edit, reinterpret_cast<char *>(n), kind);
   default:
-    io.GetIoErrorHandler().SignalError(IostatErrorInFormat,
+    handler.SignalError(IostatErrorInFormat,
         "Data edit descriptor '%c' may not be used with an INTEGER data item",
         edit.descriptor);
     return false;
@@ -217,7 +221,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
   auto fastField{io.GetUpcomingFastAsciiField()};
   char sign{ScanNumericPrefix(io, edit, next, remaining, &fastField)};
   if (sign == '-' && !isSigned) {
-    io.GetIoErrorHandler().SignalError("Negative sign in UNSIGNED input field");
+    handler.SignalError("Negative sign in UNSIGNED input field");
     return false;
   }
   common::uint128_t value{0};
@@ -254,8 +258,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
           break;
         }
       }
-      io.GetIoErrorHandler().SignalError(
-          "Bad character '%lc' in INTEGER input field", ch);
+      handler.SignalError("Bad character '%lc' in INTEGER input field", ch);
       return false;
     }
     static constexpr auto maxu128OverTen{maxu128 / 10};
@@ -268,7 +271,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
     any = true;
   }
   if (!any && !remaining) {
-    io.GetIoErrorHandler().SignalError(
+    handler.SignalError(
         "Integer value absent from NAMELIST or list-directed input");
     return false;
   }
@@ -280,14 +283,14 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
     overflow |= value >= maxForKind;
   }
   if (overflow) {
-    io.GetIoErrorHandler().SignalError(IostatIntegerInputOverflow,
+    handler.SignalError(IostatIntegerInputOverflow,
         "Decimal input overflows INTEGER(%d) variable", kind);
     return false;
   }
   if (sign == '-') {
     value = -value;
   }
-  if (any || !io.GetIoErrorHandler().InError()) {
+  if (any || !handler.InError()) {
     // The value is stored in the lower order bits on big endian platform.
     // For memcpy, shift the value to the highest order bits.
 #if USING_NATIVE_INT128_T



More information about the llvm-commits mailing list