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

via flang-commits flang-commits at lists.llvm.org
Mon Jun 30 10:21:40 PDT 2025


Author: Peter Klausler
Date: 2025-06-30T10:21:37-07:00
New Revision: a93d843ab31ac66004d939396398b798b3d013d1

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

LOG: [flang] Don't warn on (0.,0.)**(nonzero noninteger) (#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.

Added: 
    flang/test/Semantics/bug1046.f90

Modified: 
    flang/include/flang/Evaluate/complex.h
    flang/lib/Evaluate/fold-implementation.h

Removed: 
    


################################################################################
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 0154833baaf17..52e954d1cffbf 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -2192,7 +2192,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