Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion flang/include/flang/Evaluate/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,16 @@ class FoldingContext {
return common::ScopedSet(analyzingPDTComponentKindSelector_, true);
}

common::Restorer<std::string> SetRealFlagWarningContext(std::string str) {
return common::ScopedSet(realFlagWarningContext_, str);
}

parser::CharBlock SaveTempName(std::string &&name) {
return {*tempNames_.emplace(std::move(name)).first};
}

void RealFlagWarnings(const RealFlags &, const char *op);

private:
parser::ContextualMessages messages_;
const common::IntrinsicTypeDefaultKinds &defaults_;
Expand All @@ -318,8 +324,8 @@ class FoldingContext {
std::map<parser::CharBlock, ConstantSubscript> impliedDos_;
const common::LanguageFeatureControl &languageFeatures_;
std::set<std::string> &tempNames_;
std::string realFlagWarningContext_;
};

void RealFlagWarnings(FoldingContext &, const RealFlags &, const char *op);
} // namespace Fortran::evaluate
#endif // FORTRAN_EVALUATE_COMMON_H_
18 changes: 11 additions & 7 deletions flang/lib/Evaluate/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,28 @@ using namespace Fortran::parser::literals;

namespace Fortran::evaluate {

void RealFlagWarnings(
FoldingContext &context, const RealFlags &flags, const char *operation) {
void FoldingContext::RealFlagWarnings(
const RealFlags &flags, const char *operation) {
static constexpr auto warning{common::UsageWarning::FoldingException};
if (flags.test(RealFlag::Overflow)) {
context.Warn(warning, "overflow on %s"_warn_en_US, operation);
Warn(warning, "overflow on %s%s"_warn_en_US, operation,
realFlagWarningContext_);
}
if (flags.test(RealFlag::DivideByZero)) {
if (std::strcmp(operation, "division") == 0) {
context.Warn(warning, "division by zero"_warn_en_US);
Warn(warning, "division by zero%s"_warn_en_US, realFlagWarningContext_);
} else {
context.Warn(warning, "division by zero on %s"_warn_en_US, operation);
Warn(warning, "division by zero on %s%s"_warn_en_US, operation,
realFlagWarningContext_);
}
}
if (flags.test(RealFlag::InvalidArgument)) {
context.Warn(warning, "invalid argument on %s"_warn_en_US, operation);
Warn(warning, "invalid argument on %s%s"_warn_en_US, operation,
realFlagWarningContext_);
}
if (flags.test(RealFlag::Underflow)) {
context.Warn(warning, "underflow on %s"_warn_en_US, operation);
Warn(warning, "underflow on %s%s"_warn_en_US, operation,
realFlagWarningContext_);
}
}

Expand Down
14 changes: 7 additions & 7 deletions flang/lib/Evaluate/fold-implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,7 @@ Expr<TO> FoldOperation(
std::snprintf(buffer, sizeof buffer,
"INTEGER(%d) to REAL(%d) conversion", Operand::kind,
TO::kind);
RealFlagWarnings(ctx, converted.flags, buffer);
ctx.RealFlagWarnings(converted.flags, buffer);
}
return ScalarConstantToExpr(std::move(converted.value));
} else if constexpr (FromCat == TypeCategory::Real) {
Expand All @@ -1871,7 +1871,7 @@ Expr<TO> FoldOperation(
if (!converted.flags.empty()) {
std::snprintf(buffer, sizeof buffer,
"REAL(%d) to REAL(%d) conversion", Operand::kind, TO::kind);
RealFlagWarnings(ctx, converted.flags, buffer);
ctx.RealFlagWarnings(converted.flags, buffer);
}
if (ctx.targetCharacteristics().areSubnormalsFlushedToZero()) {
converted.value = converted.value.FlushSubnormalToZero();
Expand Down Expand Up @@ -2012,7 +2012,7 @@ Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
} else {
auto sum{folded->first.Add(
folded->second, context.targetCharacteristics().roundingMode())};
RealFlagWarnings(context, sum.flags, "addition");
context.RealFlagWarnings(sum.flags, "addition");
if (context.targetCharacteristics().areSubnormalsFlushedToZero()) {
sum.value = sum.value.FlushSubnormalToZero();
}
Expand Down Expand Up @@ -2041,7 +2041,7 @@ Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
} else {
auto difference{folded->first.Subtract(
folded->second, context.targetCharacteristics().roundingMode())};
RealFlagWarnings(context, difference.flags, "subtraction");
context.RealFlagWarnings(difference.flags, "subtraction");
if (context.targetCharacteristics().areSubnormalsFlushedToZero()) {
difference.value = difference.value.FlushSubnormalToZero();
}
Expand Down Expand Up @@ -2070,7 +2070,7 @@ Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
} else {
auto product{folded->first.Multiply(
folded->second, context.targetCharacteristics().roundingMode())};
RealFlagWarnings(context, product.flags, "multiplication");
context.RealFlagWarnings(product.flags, "multiplication");
if (context.targetCharacteristics().areSubnormalsFlushedToZero()) {
product.value = product.value.FlushSubnormalToZero();
}
Expand Down Expand Up @@ -2141,7 +2141,7 @@ Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
}
}
if (!isCanonicalNaNOrInf) {
RealFlagWarnings(context, quotient.flags, "division");
context.RealFlagWarnings(quotient.flags, "division");
}
if (context.targetCharacteristics().areSubnormalsFlushedToZero()) {
quotient.value = quotient.value.FlushSubnormalToZero();
Expand Down Expand Up @@ -2201,7 +2201,7 @@ Expr<T> FoldOperation(FoldingContext &context, RealToIntPower<T> &&x) {
[&](auto &y) -> Expr<T> {
if (auto folded{OperandsAreConstants(x.left(), y)}) {
auto power{evaluate::IntPower(folded->first, folded->second)};
RealFlagWarnings(context, power.flags, "power with INTEGER exponent");
context.RealFlagWarnings(power.flags, "power with INTEGER exponent");
if (context.targetCharacteristics().areSubnormalsFlushedToZero()) {
power.value = power.value.FlushSubnormalToZero();
}
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Evaluate/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ void HostFloatingPointEnvironment::CheckAndRestoreFloatingPointEnvironment(
}

if (!flags_.empty()) {
RealFlagWarnings(
context, flags_, "evaluation of intrinsic function or operation");
context.RealFlagWarnings(
flags_, "evaluation of intrinsic function or operation");
}
errno = 0;
if (fesetenv(&originalFenv_) != 0) {
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Evaluate/intrinsics-library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1043,14 +1043,16 @@ std::optional<HostRuntimeWrapper> GetHostRuntimeWrapper(const std::string &name,
if (const auto *hostFunction{
SearchHostRuntime(name, biggerResultType, biggerArgTypes)}) {
auto hostFolderWithChecks{AddArgumentVerifierIfAny(name, *hostFunction)};
return [hostFunction, resultType, hostFolderWithChecks](
return [hostFunction, resultType, hostFolderWithChecks, name](
FoldingContext &context, std::vector<Expr<SomeType>> &&args) {
auto nArgs{args.size()};
for (size_t i{0}; i < nArgs; ++i) {
args[i] = Fold(context,
ConvertToType(hostFunction->argumentTypes[i], std::move(args[i]))
.value());
}
auto restorer{context.SetRealFlagWarningContext(
" after folding a call to '"s + name + "'"s)};
return Fold(context,
ConvertToType(
resultType, hostFolderWithChecks(context, std::move(args)))
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ Constant<TYPE> ReadRealLiteral(
auto valWithFlags{
Scalar<TYPE>::Read(p, context.targetCharacteristics().roundingMode())};
CHECK(p == source.end());
RealFlagWarnings(context, valWithFlags.flags, "conversion of REAL literal");
context.RealFlagWarnings(valWithFlags.flags, "conversion of REAL literal");
auto value{valWithFlags.value};
if (context.targetCharacteristics().areSubnormalsFlushedToZero()) {
value = value.FlushSubnormalToZero();
Expand Down
4 changes: 4 additions & 0 deletions flang/test/Evaluate/folding33.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
!CHECK: warning: overflow on REAL(4) to REAL(2) conversion after folding a call to 'exp' [-Wfolding-exception]
print *, exp((11.265625_2,1._2))
end