From 5696ecdb470f1b509efc383e74a098c2e71c5f49 Mon Sep 17 00:00:00 2001 From: Peter Klausler 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 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 FoldOperation(FoldingContext &context, Power &&x) { } return Expr{Constant{power.power}}; } else { - if (auto callable{GetHostRuntimeWrapper("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(Constant{folded->first}); // 0. ** nonzero -> 0. + } + } else if (auto callable{GetHostRuntimeWrapper("pow")}) { return Expr{ Constant{(*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 + +