Skip to content

Commit a284ce8

Browse files
authored
[flang][runtime] Advance output record in specific case (llvm#167786)
When a formatted WRITE takes place in a defined output subroutine called from a context in which record advancement is allowed, such as NAMELIST, the char-string-edit-descs in the format can trigger record advancement. Also clean up confusing messiness lingering from the separation of iostat.h two headers in flang/.../Runtime. iostat.h didn't need to be put into flang/.../Runtime since it's included only by flang-rt, and iostat-consts.h doesn't need one of its includes. Fixes llvm#167757.
1 parent 3425f22 commit a284ce8

File tree

6 files changed

+20
-4
lines changed

6 files changed

+20
-4
lines changed

flang-rt/include/flang-rt/runtime/connection.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ struct ConnectionState : public ConnectionAttributes {
6666
RT_API_ATTRS bool NeedAdvance(std::size_t width) const {
6767
return positionInRecord > 0 && width > RemainingSpaceInRecord();
6868
}
69+
RT_API_ATTRS bool NeedHardAdvance(std::size_t width) const {
70+
auto recl{recordLength};
71+
if (!recl) {
72+
recl = openRecl;
73+
}
74+
return recl && positionInRecord > 0 &&
75+
static_cast<std::int64_t>(positionInRecord + width) > *recl;
76+
}
6977
RT_API_ATTRS void HandleAbsolutePosition(std::int64_t n) {
7078
positionInRecord = (n < 0 ? 0 : n) + leftTabLimit.value_or(0);
7179
}

flang-rt/include/flang-rt/runtime/format-implementation.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,9 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit(
430430
if constexpr (std::is_base_of_v<InputStatementState, CONTEXT>) {
431431
context.HandleRelativePosition(chars);
432432
} else {
433+
if (context.GetConnectionState().NeedHardAdvance(chars)) {
434+
context.AdvanceRecord();
435+
}
433436
EmitAscii(context, format_ + start, chars);
434437
}
435438
} else if (ch == 'H') {
@@ -442,6 +445,9 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit(
442445
if constexpr (std::is_base_of_v<InputStatementState, CONTEXT>) {
443446
context.HandleRelativePosition(static_cast<std::size_t>(*repeat));
444447
} else {
448+
if (context.GetConnectionState().NeedHardAdvance(*repeat)) {
449+
context.AdvanceRecord();
450+
}
445451
EmitAscii(
446452
context, format_ + offset_, static_cast<std::size_t>(*repeat));
447453
}
@@ -487,6 +493,9 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit(
487493
} else if (ch == '\t' || ch == '\v') {
488494
// Tabs (extension)
489495
// TODO: any other raw characters?
496+
if (context.GetConnectionState().NeedHardAdvance(1)) {
497+
context.AdvanceRecord();
498+
}
490499
EmitAscii(context, format_ + offset_ - 1, 1);
491500
} else {
492501
ReportBadFormat(

flang-rt/include/flang-rt/runtime/io-error.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
#ifndef FLANG_RT_RUNTIME_IO_ERROR_H_
1616
#define FLANG_RT_RUNTIME_IO_ERROR_H_
1717

18+
#include "iostat.h"
1819
#include "memory.h"
1920
#include "terminator.h"
20-
#include "flang/Runtime/iostat.h"
2121
#include <cinttypes>
2222

2323
namespace Fortran::runtime::io {

flang/include/flang/Runtime/iostat.h renamed to flang-rt/include/flang-rt/runtime/iostat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- include/flang/Runtime/iostat.h --------------------------*- C++ -*-===//
1+
//===-- include/flang-rt/runtime/iostat.h -----------------------*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.

flang-rt/lib/runtime/iostat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "flang/Runtime/iostat.h"
9+
#include "flang-rt/runtime/iostat.h"
1010

1111
namespace Fortran::runtime::io {
1212
RT_OFFLOAD_API_GROUP_BEGIN

flang/include/flang/Runtime/iostat-consts.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#ifndef FORTRAN_RUNTIME_IOSTAT_CONSTS_H_
1010
#define FORTRAN_RUNTIME_IOSTAT_CONSTS_H_
1111

12-
#include "flang/Common/api-attrs.h"
1312
#include "flang/Runtime/magic-numbers.h"
1413

1514
namespace Fortran::runtime::io {

0 commit comments

Comments
 (0)