xref: /llvm-project/flang/lib/Evaluate/common.cpp (revision 0f973ac783aa100cfbce1cd2c6e8a3a8f648fae7)
164ab3302SCarolineConcatto //===-- lib/Evaluate/common.cpp -------------------------------------------===//
264ab3302SCarolineConcatto //
364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information.
564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
664ab3302SCarolineConcatto //
764ab3302SCarolineConcatto //===----------------------------------------------------------------------===//
864ab3302SCarolineConcatto 
964ab3302SCarolineConcatto #include "flang/Evaluate/common.h"
1064ab3302SCarolineConcatto #include "flang/Common/idioms.h"
1164ab3302SCarolineConcatto 
1264ab3302SCarolineConcatto using namespace Fortran::parser::literals;
1364ab3302SCarolineConcatto 
1464ab3302SCarolineConcatto namespace Fortran::evaluate {
1564ab3302SCarolineConcatto 
1664ab3302SCarolineConcatto void RealFlagWarnings(
1764ab3302SCarolineConcatto     FoldingContext &context, const RealFlags &flags, const char *operation) {
18*0f973ac7SPeter Klausler   static constexpr auto warning{common::UsageWarning::FoldingException};
19*0f973ac7SPeter Klausler   if (context.languageFeatures().ShouldWarn(warning)) {
2064ab3302SCarolineConcatto     if (flags.test(RealFlag::Overflow)) {
21*0f973ac7SPeter Klausler       context.messages().Say(warning, "overflow on %s"_warn_en_US, operation);
2264ab3302SCarolineConcatto     }
2364ab3302SCarolineConcatto     if (flags.test(RealFlag::DivideByZero)) {
2429fa4518Speter klausler       if (std::strcmp(operation, "division") == 0) {
25*0f973ac7SPeter Klausler         context.messages().Say(warning, "division by zero"_warn_en_US);
2629fa4518Speter klausler       } else {
27*0f973ac7SPeter Klausler         context.messages().Say(
28*0f973ac7SPeter Klausler             warning, "division by zero on %s"_warn_en_US, operation);
2929fa4518Speter klausler       }
3064ab3302SCarolineConcatto     }
3164ab3302SCarolineConcatto     if (flags.test(RealFlag::InvalidArgument)) {
32*0f973ac7SPeter Klausler       context.messages().Say(
33*0f973ac7SPeter Klausler           warning, "invalid argument on %s"_warn_en_US, operation);
3464ab3302SCarolineConcatto     }
3564ab3302SCarolineConcatto     if (flags.test(RealFlag::Underflow)) {
36*0f973ac7SPeter Klausler       context.messages().Say(warning, "underflow on %s"_warn_en_US, operation);
3764ab3302SCarolineConcatto     }
3864ab3302SCarolineConcatto   }
39505f6da1SPeter Klausler }
4064ab3302SCarolineConcatto 
4164ab3302SCarolineConcatto ConstantSubscript &FoldingContext::StartImpliedDo(
4264ab3302SCarolineConcatto     parser::CharBlock name, ConstantSubscript n) {
4364ab3302SCarolineConcatto   auto pair{impliedDos_.insert(std::make_pair(name, n))};
4464ab3302SCarolineConcatto   CHECK(pair.second);
4564ab3302SCarolineConcatto   return pair.first->second;
4664ab3302SCarolineConcatto }
4764ab3302SCarolineConcatto 
4864ab3302SCarolineConcatto std::optional<ConstantSubscript> FoldingContext::GetImpliedDo(
4964ab3302SCarolineConcatto     parser::CharBlock name) const {
5064ab3302SCarolineConcatto   if (auto iter{impliedDos_.find(name)}; iter != impliedDos_.cend()) {
5164ab3302SCarolineConcatto     return {iter->second};
5264ab3302SCarolineConcatto   } else {
5364ab3302SCarolineConcatto     return std::nullopt;
5464ab3302SCarolineConcatto   }
5564ab3302SCarolineConcatto }
5664ab3302SCarolineConcatto 
5764ab3302SCarolineConcatto void FoldingContext::EndImpliedDo(parser::CharBlock name) {
5864ab3302SCarolineConcatto   auto iter{impliedDos_.find(name)};
5964ab3302SCarolineConcatto   if (iter != impliedDos_.end()) {
6064ab3302SCarolineConcatto     impliedDos_.erase(iter);
6164ab3302SCarolineConcatto   }
6264ab3302SCarolineConcatto }
631f879005STim Keith } // namespace Fortran::evaluate
64