[flang-commits] [flang] 56b7db9 - [flang] Change error to portability warning

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Dec 2 13:45:57 PST 2022


Author: Peter Klausler
Date: 2022-12-02T13:45:41-08:00
New Revision: 56b7db9e07f6d792a665a7731f91d5f81be85547

URL: https://github.com/llvm/llvm-project/commit/56b7db9e07f6d792a665a7731f91d5f81be85547
DIFF: https://github.com/llvm/llvm-project/commit/56b7db9e07f6d792a665a7731f91d5f81be85547.diff

LOG: [flang] Change error to portability warning

The standard does *not* require that a real or imaginary part of a complex
literal constant be a scalar if it is a named constant.  Downgrade a
recently installed check to a portability warning, and document it.

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

Added: 
    

Modified: 
    flang/docs/Extensions.md
    flang/include/flang/Semantics/expression.h
    flang/lib/Semantics/expression.cpp
    flang/test/Semantics/expr-errors05.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index d0d715db19e84..ed0229d9c2eba 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -350,6 +350,10 @@ end
   pointer-valued function reference.
   No other Fortran compiler seems to handle this correctly for
   `ASSOCIATE`, though NAG gets it right for `SELECT TYPE`.
+* The standard doesn't explicitly require that a named constant that
+  appears as part of a complex-literal-constant be a scalar, but
+  most compilers emit an error when an array appears.
+  f18 supports them with a portability warning.
 
 ## Behavior in cases where the standard is ambiguous or indefinite
 

diff  --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index 0b170cf79ca74..a6ed85b0dbf95 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -369,6 +369,7 @@ class ExpressionAnalyzer {
     return evaluate::Fold(foldingContext_, std::move(expr));
   }
   bool CheckIsValidForwardReference(const semantics::DerivedTypeSpec &);
+  MaybeExpr AnalyzeComplex(MaybeExpr &&re, MaybeExpr &&im, const char *what);
 
   semantics::SemanticsContext &context_;
   FoldingContext &foldingContext_{context_.foldingContext()};

diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 9e53d30867183..88de21373be6d 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -698,9 +698,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ComplexPart &x) {
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::ComplexLiteralConstant &z) {
-  return AsMaybeExpr(
-      ConstructComplex(GetContextualMessages(), Analyze(std::get<0>(z.t)),
-          Analyze(std::get<1>(z.t)), GetDefaultKind(TypeCategory::Real)));
+  return AnalyzeComplex(Analyze(std::get<0>(z.t)), Analyze(std::get<1>(z.t)),
+      "complex literal constant");
 }
 
 // CHARACTER literal processing.
@@ -2861,22 +2860,9 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Subtract &x) {
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(
-    const parser::Expr::ComplexConstructor &x) {
-  auto re{Analyze(std::get<0>(x.t).value())};
-  auto im{Analyze(std::get<1>(x.t).value())};
-  if (re && re->Rank() > 0) {
-    context().Say(std::get<0>(x.t).value().source,
-        "Real part of complex constructor must be scalar"_err_en_US);
-  }
-  if (im && im->Rank() > 0) {
-    context().Say(std::get<1>(x.t).value().source,
-        "Imaginary part of complex constructor must be scalar"_err_en_US);
-  }
-  if (re && im) {
-    ConformabilityCheck(GetContextualMessages(), *re, *im);
-  }
-  return AsMaybeExpr(ConstructComplex(GetContextualMessages(), std::move(re),
-      std::move(im), GetDefaultKind(TypeCategory::Real)));
+    const parser::Expr::ComplexConstructor &z) {
+  return AnalyzeComplex(Analyze(std::get<0>(z.t).value()),
+      Analyze(std::get<1>(z.t).value()), "complex constructor");
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Concat &x) {
@@ -3391,6 +3377,21 @@ MaybeExpr ExpressionAnalyzer::MakeFunctionRef(
   }
 }
 
+MaybeExpr ExpressionAnalyzer::AnalyzeComplex(
+    MaybeExpr &&re, MaybeExpr &&im, const char *what) {
+  if (re && re->Rank() > 0) {
+    Say("Real part of %s is not scalar"_port_en_US, what);
+  }
+  if (im && im->Rank() > 0) {
+    Say("Imaginary part of %s is not scalar"_port_en_US, what);
+  }
+  if (re && im) {
+    ConformabilityCheck(GetContextualMessages(), *re, *im);
+  }
+  return AsMaybeExpr(ConstructComplex(GetContextualMessages(), std::move(re),
+      std::move(im), GetDefaultKind(TypeCategory::Real)));
+}
+
 void ArgumentAnalyzer::Analyze(const parser::Variable &x) {
   source_.ExtendToCover(x.GetSource());
   if (MaybeExpr expr{context_.Analyze(x)}) {

diff  --git a/flang/test/Semantics/expr-errors05.f90 b/flang/test/Semantics/expr-errors05.f90
index 1f1a7c51813b5..964511888d5ef 100644
--- a/flang/test/Semantics/expr-errors05.f90
+++ b/flang/test/Semantics/expr-errors05.f90
@@ -1,7 +1,14 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
-! The components of a complex constructor (extension) must be scalar
-!ERROR: Real part of complex constructor must be scalar
+! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
+!PORTABILITY: Real part of complex constructor is not scalar
 complex, parameter :: z1(*) = ([1.,2.], 3.)
-!ERROR: Imaginary part of complex constructor must be scalar
+!PORTABILITY: Imaginary part of complex constructor is not scalar
 complex, parameter :: z2(*) = (4., [5.,6.])
+real, parameter :: aa(*) = [7.,8.]
+!PORTABILITY: Real part of complex literal constant is not scalar
+complex, parameter :: z3(*) = (aa, 9.)
+!PORTABILITY: Imaginary part of complex literal constant is not scalar
+complex, parameter :: z4(*) = (10., aa)
+!We need a nonzero exit status to make test_errors.py look at messages :-(
+!WARNING: division by zero
+real, parameter :: xxx = 1./0.
 end


        


More information about the flang-commits mailing list