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