164ab3302SCarolineConcatto //===-- lib/Semantics/check-return.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-return.h" 1064ab3302SCarolineConcatto #include "flang/Common/Fortran-features.h" 1164ab3302SCarolineConcatto #include "flang/Parser/message.h" 1264ab3302SCarolineConcatto #include "flang/Parser/parse-tree.h" 1364ab3302SCarolineConcatto #include "flang/Semantics/semantics.h" 1464ab3302SCarolineConcatto #include "flang/Semantics/tools.h" 1564ab3302SCarolineConcatto 1664ab3302SCarolineConcatto namespace Fortran::semantics { 1764ab3302SCarolineConcatto 1864ab3302SCarolineConcatto static const Scope *FindContainingSubprogram(const Scope &start) { 191f525eceSTim Keith const Scope &scope{GetProgramUnitContaining(start)}; 201f525eceSTim Keith return scope.kind() == Scope::Kind::MainProgram || 211f525eceSTim Keith scope.kind() == Scope::Kind::Subprogram 221f525eceSTim Keith ? &scope 2364ab3302SCarolineConcatto : nullptr; 2464ab3302SCarolineConcatto } 2564ab3302SCarolineConcatto 2664ab3302SCarolineConcatto void ReturnStmtChecker::Leave(const parser::ReturnStmt &returnStmt) { 2764ab3302SCarolineConcatto // R1542 Expression analysis validates the scalar-int-expr 2864ab3302SCarolineConcatto // C1574 The return-stmt shall be in the inclusive scope of a function or 2964ab3302SCarolineConcatto // subroutine subprogram. 3064ab3302SCarolineConcatto // C1575 The scalar-int-expr is allowed only in the inclusive scope of a 3164ab3302SCarolineConcatto // subroutine subprogram. 3264ab3302SCarolineConcatto const auto &scope{context_.FindScope(context_.location().value())}; 3364ab3302SCarolineConcatto if (const auto *subprogramScope{FindContainingSubprogram(scope)}) { 3464ab3302SCarolineConcatto if (returnStmt.v && 3564ab3302SCarolineConcatto (subprogramScope->kind() == Scope::Kind::MainProgram || 3664ab3302SCarolineConcatto IsFunction(*subprogramScope->GetSymbol()))) { 3764ab3302SCarolineConcatto context_.Say( 3864ab3302SCarolineConcatto "RETURN with expression is only allowed in SUBROUTINE subprogram"_err_en_US); 39*0f973ac7SPeter Klausler } else if (subprogramScope->kind() == Scope::Kind::MainProgram) { 40*0f973ac7SPeter Klausler context_.Warn(common::LanguageFeature::ProgramReturn, 41*0f973ac7SPeter Klausler "RETURN should not appear in a main program"_port_en_US); 4264ab3302SCarolineConcatto } 4364ab3302SCarolineConcatto } 4464ab3302SCarolineConcatto } 4564ab3302SCarolineConcatto 461f879005STim Keith } // namespace Fortran::semantics 47