[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.
This commit is contained in:
Peter Klausler 2025-06-30 10:21:37 -07:00 committed by GitHub
parent 348002e111
commit a93d843ab3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 2 deletions

View File

@ -45,7 +45,7 @@ public:
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();

View File

@ -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(

View File

@ -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