[flang-commits] [flang] [flang] Don't warn on (0., 0.)**(nonzero noninteger) (PR #145179)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sat Jun 21 11:03:14 PDT 2025


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/145179

Folding hands complex exponentiations with constant arguments off to the native libm, and on a least on host, this can produce spurious warnings about division by zero and invalid arguments.  Handle the case of a zero base specially to avoid that, and also emit better warnings for the undefined 0.**0 and (0.,0.)**0 cases. And add a test for these warnings and the existing related ones.

>From 5696ecdb470f1b509efc383e74a098c2e71c5f49 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Sat, 21 Jun 2025 10:58:46 -0700
Subject: [PATCH] [flang] Don't warn on (0.,0.)**(nonzero noninteger)

Folding hands complex exponentiations with constant arguments off to
the native libm, and on a least on host, this can produce spurious
warnings about division by zero and invalid arguments.  Handle
the case of a zero base specially to avoid that, and also emit
better warnings for the undefined 0.**0 and (0.,0.)**0 cases.
And add a test for these warnings and the existing related ones.
---
 flang/include/flang/Evaluate/complex.h   |  2 +-
 flang/lib/Evaluate/fold-implementation.h |  9 ++++++++-
 flang/test/Semantics/bug1046.f90         | 17 +++++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 flang/test/Semantics/bug1046.f90

diff --git a/flang/include/flang/Evaluate/complex.h b/flang/include/flang/Evaluate/complex.h
index 2dcd28b59968c..720ccaf512df6 100644
--- a/flang/include/flang/Evaluate/complex.h
+++ b/flang/include/flang/Evaluate/complex.h
@@ -45,7 +45,7 @@ template <typename REAL_TYPE> class Complex {
         im_.Compare(that.im_) == Relation::Equal;
   }
 
-  constexpr bool IsZero() const { return re_.IsZero() || im_.IsZero(); }
+  constexpr bool IsZero() const { return re_.IsZero() && im_.IsZero(); }
 
   constexpr bool IsInfinite() const {
     return re_.IsInfinite() || im_.IsInfinite();
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index b0f39e63d0941..b3780cea4e076 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -2156,7 +2156,14 @@ Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
       }
       return Expr<T>{Constant<T>{power.power}};
     } else {
-      if (auto callable{GetHostRuntimeWrapper<T, T, T>("pow")}) {
+      if (folded->first.IsZero()) {
+        if (folded->second.IsZero()) {
+          context.messages().Say(common::UsageWarning::FoldingException,
+              "REAL/COMPLEX 0**0 is not defined"_warn_en_US);
+        } else {
+          return Expr<T>(Constant<T>{folded->first}); // 0. ** nonzero -> 0.
+        }
+      } else if (auto callable{GetHostRuntimeWrapper<T, T, T>("pow")}) {
         return Expr<T>{
             Constant<T>{(*callable)(context, folded->first, folded->second)}};
       } else if (context.languageFeatures().ShouldWarn(
diff --git a/flang/test/Semantics/bug1046.f90 b/flang/test/Semantics/bug1046.f90
new file mode 100644
index 0000000000000..a266651f90c31
--- /dev/null
+++ b/flang/test/Semantics/bug1046.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror
+!WARNING: INTEGER(4) 0**0 is not defined
+print *, 0**0
+!WARNING: REAL/COMPLEX 0**0 is not defined
+print *, 0**0.
+!WARNING: invalid argument on power with INTEGER exponent
+print *, 0.0**0
+!WARNING: REAL/COMPLEX 0**0 is not defined
+print *, 0.0**0.
+!WARNING: invalid argument on power with INTEGER exponent
+print *, (0.0, 0.0)**0
+!WARNING: REAL/COMPLEX 0**0 is not defined
+print *, (0.0, 0.0)**0.
+print *, (0.0, 0.0)**2.5
+end
+
+



More information about the flang-commits mailing list