xref: /llvm-project/flang/lib/Semantics/check-arithmeticif.cpp (revision fc97d2e68b03bc2979395e84b645e5b3ba35aecd)
164ab3302SCarolineConcatto //===-- lib/Semantics/check-arithmeticif.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 "check-arithmeticif.h"
1064ab3302SCarolineConcatto #include "flang/Parser/message.h"
1164ab3302SCarolineConcatto #include "flang/Parser/parse-tree.h"
1264ab3302SCarolineConcatto #include "flang/Semantics/tools.h"
1364ab3302SCarolineConcatto 
1464ab3302SCarolineConcatto namespace Fortran::semantics {
1564ab3302SCarolineConcatto 
1664ab3302SCarolineConcatto bool IsNumericExpr(const SomeExpr &expr) {
1764ab3302SCarolineConcatto   auto dynamicType{expr.GetType()};
1864ab3302SCarolineConcatto   return dynamicType && common::IsNumericTypeCategory(dynamicType->category());
1964ab3302SCarolineConcatto }
2064ab3302SCarolineConcatto 
2164ab3302SCarolineConcatto void ArithmeticIfStmtChecker::Leave(
2264ab3302SCarolineConcatto     const parser::ArithmeticIfStmt &arithmeticIfStmt) {
2364ab3302SCarolineConcatto   // Arithmetic IF statements have been removed from Fortran 2018.
2464ab3302SCarolineConcatto   // The constraints and requirements here refer to the 2008 spec.
2564ab3302SCarolineConcatto   // R853 Check for a scalar-numeric-expr
2664ab3302SCarolineConcatto   // C849 that shall not be of type complex.
2764ab3302SCarolineConcatto   auto &parsedExpr{std::get<parser::Expr>(arithmeticIfStmt.t)};
287e225423SPeter Klausler   if (const auto *expr{GetExpr(context_, parsedExpr)}) {
2964ab3302SCarolineConcatto     if (expr->Rank() > 0) {
3064ab3302SCarolineConcatto       context_.Say(parsedExpr.source,
3164ab3302SCarolineConcatto           "ARITHMETIC IF expression must be a scalar expression"_err_en_US);
3264ab3302SCarolineConcatto     } else if (ExprHasTypeCategory(*expr, common::TypeCategory::Complex)) {
3364ab3302SCarolineConcatto       context_.Say(parsedExpr.source,
3464ab3302SCarolineConcatto           "ARITHMETIC IF expression must not be a COMPLEX expression"_err_en_US);
35*fc97d2e6SPeter Klausler     } else if (ExprHasTypeCategory(*expr, common::TypeCategory::Unsigned)) {
36*fc97d2e6SPeter Klausler       context_.Say(parsedExpr.source,
37*fc97d2e6SPeter Klausler           "ARITHMETIC IF expression must not be an UNSIGNED expression"_err_en_US);
3864ab3302SCarolineConcatto     } else if (!IsNumericExpr(*expr)) {
3964ab3302SCarolineConcatto       context_.Say(parsedExpr.source,
4064ab3302SCarolineConcatto           "ARITHMETIC IF expression must be a numeric expression"_err_en_US);
4164ab3302SCarolineConcatto     }
4264ab3302SCarolineConcatto   }
4364ab3302SCarolineConcatto   // The labels have already been checked in resolve-labels.
4464ab3302SCarolineConcatto   // TODO: Really?  Check that they are really branch target
4564ab3302SCarolineConcatto   // statements and in the same inclusive scope.
4664ab3302SCarolineConcatto }
4764ab3302SCarolineConcatto 
4864ab3302SCarolineConcatto } // namespace Fortran::semantics
49