Unverified Commit ab261eb3 authored by jeanPerier's avatar jeanPerier Committed by GitHub
Browse files

[flang] Do not stop on mismatched DATA substring length (#69336)

https://reviews.llvm.org/D143819 turned mismatched DATA substring from a
crash into a warning. However, the resulting DATA was incorrect when
there were subsequent DATA values after the mismatch because the DATA to
init conversion stopped. This change let the DATA to init continue.

I added a LengthMismatch tag instead of using SizeMismatch because the
other situation where SizeMismatch is returned seem like bug situations
to me (the DATA value is dropped and the offset is not advanced), so I
did not want to continue DATA processing in these cases.
parent 5c3ed392
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ namespace Fortran::evaluate {

class InitialImage {
public:
  enum Result { Ok, NotAConstant, OutOfRange, SizeMismatch };
  enum Result { Ok, NotAConstant, OutOfRange, SizeMismatch, LengthMismatch };

  explicit InitialImage(std::size_t bytes) : data_(bytes) {}
  InitialImage(InitialImage &&that) = default;
@@ -72,7 +72,7 @@ public:
          auto scalar{x.At(at)}; // this is a std string; size() in chars
          auto scalarBytes{scalar.size() * KIND};
          if (scalarBytes != elementBytes) {
            result = SizeMismatch;
            result = LengthMismatch;
          }
          // Blank padding when short
          for (; scalarBytes < elementBytes; scalarBytes += KIND) {
+2 −1
Original line number Diff line number Diff line
@@ -457,10 +457,11 @@ bool DataInitializationCompiler<DSV>::InitElement(
            folded.AsFortran(), DescribeElement());
      } else if (status == evaluate::InitialImage::OutOfRange) {
        OutOfRangeError();
      } else if (status == evaluate::InitialImage::SizeMismatch) {
      } else if (status == evaluate::InitialImage::LengthMismatch) {
        exprAnalyzer_.Say(
            "DATA statement value '%s' for '%s' has the wrong length"_warn_en_US,
            folded.AsFortran(), DescribeElement());
        return true;
      } else {
        CHECK(exprAnalyzer_.context().AnyFatalError());
      }
+13 −0
Original line number Diff line number Diff line
! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
! Test truncation/padding in DATA statement.

  character(len=3) :: c1, c2, c3(2), c4(2)
  data c1(1:2), c1(3:3) /'123', '4'/
  data c2(1:2), c2(3:3) /'1', '2'/
  data c3(:)(1:2), c3(:)(3:3) /'123', '678', '4', '9'/
  data c4(:)(1:2), c4(:)(3:3) /'1', '6', '2', '7'/
end
!CHECK:  c1 (InDataStmt) size=3 offset=0: ObjectEntity type: CHARACTER(3_4,1) init:"124"
!CHECK:  c2 (InDataStmt) size=3 offset=3: ObjectEntity type: CHARACTER(3_4,1) init:"1 2"
!CHECK:  c3 (InDataStmt) size=6 offset=6: ObjectEntity type: CHARACTER(3_4,1) shape: 1_8:2_8 init:[CHARACTER(KIND=1,LEN=3)::"124","679"]
!CHECK:  c4 (InDataStmt) size=6 offset=12: ObjectEntity type: CHARACTER(3_4,1) shape: 1_8:2_8 init:[CHARACTER(KIND=1,LEN=3)::"1 2","6 7"]