[flang-commits] [flang] [flang][runtime] Fix BACKSPACE-WRITE on variable-length unformatted file (PR #72732)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Nov 17 17:39:43 PST 2023


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

A subtle bug in buffer management is being caused by a WRITE on an unformatted file with variable-length records after one or more BACKSPACEs and some READs.  An attempt at a minor optimization in BACKSPACE kept the footer of the previous record in the unit's buffer, in case more BACKSPACEs were to follow.  If a later WRITE takes place instead, the buffer's frame would still cover that footer, but its content would be lost when the buffer became dirty on its first modification, and the footer in the file would be overwritten with stale buffer contents.  As WriteFrame() implies the intent to define all the bytes in the identified range, the trick being used in BACKSPACE with its adjustment to frameOffsetInFile_ breaks any later WRITE... and so we just can't do it.

Fixes https://github.com/llvm/llvm-project/issues/72599.

>From 0263ff49ca8e505c0b08ce3671cebadac77ebbf9 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Fri, 17 Nov 2023 17:26:02 -0800
Subject: [PATCH] [flang][runtime] Fix BACKSPACE-WRITE on variable-length
 unformatted file

A subtle bug in buffer management is being caused by a WRITE
on an unformatted file with variable-length records after one
or more BACKSPACEs and some READs.  An attempt at a minor
optimization in BACKSPACE kept the footer of the previous
record in the unit's buffer, in case more BACKSPACEs were
to follow.  If a later WRITE takes place instead, the buffer's
frame would still cover that footer, but its content would be
lost when the buffer became dirty on its first modification,
and the footer in the file would be overwritten with stale
buffer contents.  As WriteFrame() implies the intent to define
all the bytes in the identified range, the trick being used in
BACKSPACE with its adjustment to frameOffsetInFile_ breaks any
later WRITE... and so we just can't do it.

Fixes https://github.com/llvm/llvm-project/issues/72599.
---
 flang/runtime/unit.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index dec8d8032f6155e..995656b9480c414 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -825,10 +825,6 @@ void ExternalFileUnit::BackspaceVariableUnformattedRecord(
     return;
   }
   frameOffsetInFile_ -= *recordLength + 2 * headerBytes;
-  if (frameOffsetInFile_ >= headerBytes) {
-    frameOffsetInFile_ -= headerBytes;
-    recordOffsetInFrame_ = headerBytes;
-  }
   auto need{static_cast<std::size_t>(
       recordOffsetInFrame_ + sizeof header + *recordLength)};
   got = ReadFrame(frameOffsetInFile_, need, handler);



More information about the flang-commits mailing list