[flang] Complex expression dump fixes
authorJean Perier <jperier@nvidia.com>
Tue, 3 Dec 2019 15:52:18 +0000 (07:52 -0800)
committerJean Perier <jperier@nvidia.com>
Tue, 3 Dec 2019 17:28:33 +0000 (09:28 -0800)
1. Dump negative parts in complex constants without parentheses

(-1., 0.) was dumped as ((-1.), 0.) from f18 expression format.
The latter format is only valid with the complex constructor extension
that is not supported by all compilers.
This commit ensure the former fromat is used in dumps so that dumps can
be used by all fortran compilers. It turns out the parenthesis added
by REAL::AsFortran are not required because operation lowering is
already taking care of this.

2. Dump evaluate::ComplexComponent with REAL/IMAG instead of %RE/%IM

f18 was failing to reparse its own dump in some cases involving
complex expressions like `-z**i`.
The reason was %RE and %IM were used to dump ComplexComponents.
%RE and %IM can only be used on designators but ComplexComponent can
contain arbitrary complex expressions.
Hence, %RE and %IM cannot be used to dump ComplexComponent.
This commit replace them with call to intrinsic function
REAL/IMAG.
Note that this may unfortunatly be unsafe if the user
shadowed REAL or IMAG but I do not see an easy way to solve
this... The current dump is not correct.

Original-commit: flang-compiler/f18@4550a23d0bdce4ffa8d8765a1da4b35151eebe50
Reviewed-on: https://github.com/flang-compiler/f18/pull/851

flang/lib/evaluate/expression.h
flang/lib/evaluate/real.cc
flang/test/semantics/modfile20.f90

index 5456e66..560f70a 100644 (file)
@@ -257,7 +257,8 @@ struct ComplexComponent
   ComplexComponent(bool isImaginary, Expr<Operand> &&x)
     : Base{std::move(x)}, isImaginaryPart{isImaginary} {}
 
-  const char *Suffix() const { return isImaginaryPart ? "%IM" : "%RE"; }
+  const char *Prefix() const { return isImaginaryPart ? "IMAG(" : "REAL("; }
+  const char *Suffix() const { return ")"; }
 
   bool isImaginaryPart{true};
 };
index 69f3562..7cc3a4b 100644 (file)
@@ -470,10 +470,6 @@ std::ostream &Real<W, P, IM>::AsFortran(
       o << "(1._" << kind << "/0.)";
     }
   } else {
-    bool parenthesize{IsNegative()};
-    if (parenthesize) {
-      o << "(";
-    }
     using B = decimal::BinaryFloatingPointNumber<P>;
     const auto *value{reinterpret_cast<const B *>(this)};
     char buffer[24000];  // accommodate real*16
@@ -496,9 +492,6 @@ std::ostream &Real<W, P, IM>::AsFortran(
       o << 'e' << expo;
     }
     o << '_' << kind;
-    if (parenthesize) {
-      o << ')';
-    }
   }
   return o;
 }
index da230e4..ceb2759 100644 (file)
@@ -22,6 +22,7 @@ module m
   character(10, kind=k1) :: c = k1_"asdf"
   character(10), parameter :: c2 = k1_"qwer"
   complex*16, parameter :: z = (1.0_k8, 2.0_k8)
+  complex*16, parameter :: zn = (-1.0_k8, 2.0_k8)
   type t
     integer :: a = 123
     type(t), pointer :: b => null()
@@ -40,6 +41,7 @@ end
 !  character(10_4,1)::c
 !  character(10_4,1),parameter::c2=1_"qwer      "
 !  complex(8),parameter::z=(1._8,2._8)
+!  complex(8),parameter::zn=(-1._8,2._8)
 !  type::t
 !    integer(4)::a=123_4
 !    type(t),pointer::b=>NULL()