[flang] Roll up small fixes to runtime bugs found in testing
authorpeter klausler <pklausler@nvidia.com>
Thu, 18 Jun 2020 19:19:49 +0000 (12:19 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 18 Jun 2020 21:25:04 +0000 (14:25 -0700)
Summary:
Fix several bugs in the Fortran runtime found in initial
testing.

Reviewers: tskeith, PeteSteinfeld, sscalpone, jdoerfert, DavidTruby

Reviewed By: tskeith, PeteSteinfeld

Subscribers: llvm-commits, flang-commits

Tags: #flang, #llvm

Differential Revision: https://reviews.llvm.org/D82116

flang/runtime/connection.h
flang/runtime/format-implementation.h
flang/runtime/stop.cpp
flang/runtime/unit.cpp

index 67d4d77..d45ccfb 100644 (file)
@@ -40,7 +40,7 @@ struct ConnectionState : public ConnectionAttributes {
   // Positions in a record file (sequential or direct, not stream)
   std::int64_t currentRecordNumber{1}; // 1 is first
   std::int64_t positionInRecord{0}; // offset in current record
-  std::int64_t furthestPositionInRecord{0}; // max(positionInRecord)
+  std::int64_t furthestPositionInRecord{0}; // max(position+bytes)
   bool nonAdvancing{false}; // ADVANCE='NO'
 
   // Set at end of non-advancing I/O data transfer
index 21cb41c..ce0e08b 100644 (file)
@@ -225,14 +225,14 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
   while (true) {
     std::optional<int> repeat;
     bool unlimited{false};
-    CharType ch{Capitalize(GetNextChar(context))};
+    CharType ch{GetNextChar(context)};
     while (ch == ',' || ch == ':') {
       // Skip commas, and don't complain if they're missing; the format
       // validator does that.
       if (stop && ch == ':') {
         return 0;
       }
-      ch = Capitalize(GetNextChar(context));
+      ch = GetNextChar(context);
     }
     if (ch == '-' || ch == '+' || (ch >= '0' && ch <= '9')) {
       repeat = GetIntField(context, ch);
@@ -246,6 +246,7 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
         return 0;
       }
     }
+    ch = Capitalize(ch);
     if (ch == '(') {
       if (height_ >= maxHeight_) {
         context.SignalError(IostatErrorInFormat,
index 321b060..cd91b77 100644 (file)
@@ -42,8 +42,14 @@ static void DescribeIEEESignaledExceptions() {
   }
 }
 
+static void CloseAllExternalUnits(const char *why) {
+  Fortran::runtime::io::IoErrorHandler handler{why};
+  Fortran::runtime::io::ExternalFileUnit::CloseAll(handler);
+}
+
 [[noreturn]] void RTNAME(StopStatement)(
     int code, bool isErrorStop, bool quiet) {
+  CloseAllExternalUnits("STOP statement");
   if (!quiet) {
     if (code != EXIT_SUCCESS) {
       std::fprintf(stderr, "Fortran %s: code %d\n",
@@ -56,6 +62,7 @@ static void DescribeIEEESignaledExceptions() {
 
 [[noreturn]] void RTNAME(StopStatementText)(
     const char *code, bool isErrorStop, bool quiet) {
+  CloseAllExternalUnits("STOP statement");
   if (!quiet) {
     std::fprintf(
         stderr, "Fortran %s: %s\n", isErrorStop ? "ERROR STOP" : "STOP", code);
@@ -66,12 +73,12 @@ static void DescribeIEEESignaledExceptions() {
 
 [[noreturn]] void RTNAME(FailImageStatement)() {
   Fortran::runtime::NotifyOtherImagesOfFailImageStatement();
+  CloseAllExternalUnits("FAIL IMAGE statement");
   std::exit(EXIT_FAILURE);
 }
 
 [[noreturn]] void RTNAME(ProgramEndStatement)() {
-  Fortran::runtime::io::IoErrorHandler handler{"END statement"};
-  Fortran::runtime::io::ExternalFileUnit::CloseAll(handler);
+  CloseAllExternalUnits("END statement");
   std::exit(EXIT_SUCCESS);
 }
 }
index 0661d55..81035ab 100644 (file)
@@ -129,6 +129,10 @@ bool ExternalFileUnit::Emit(
     return false;
   }
   WriteFrame(frameOffsetInFile_, recordOffsetInFrame_ + furthestAfter, handler);
+  if (positionInRecord > furthestPositionInRecord) {
+    std::memset(Frame() + furthestPositionInRecord, ' ',
+        positionInRecord - furthestPositionInRecord);
+  }
   std::memcpy(Frame() + positionInRecord, data, bytes);
   positionInRecord += bytes;
   furthestPositionInRecord = furthestAfter;
@@ -189,7 +193,7 @@ bool ExternalFileUnit::AdvanceRecord(IoErrorHandler &handler) {
             ' ', *recordLength - furthestPositionInRecord);
       }
     } else {
-      positionInRecord = furthestPositionInRecord + 1;
+      positionInRecord = furthestPositionInRecord;
       ok &= Emit("\n", 1, handler); // TODO: Windows CR+LF
       frameOffsetInFile_ += recordOffsetInFrame_ + furthestPositionInRecord;
       recordOffsetInFrame_ = 0;