1 //===-- lib/Semantics/check-deallocate.cpp --------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "check-deallocate.h" 10 #include "flang/Parser/message.h" 11 #include "flang/Parser/parse-tree.h" 12 #include "flang/Semantics/expression.h" 13 #include "flang/Semantics/tools.h" 14 15 namespace Fortran::semantics { 16 17 void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) { 18 for (const parser::AllocateObject &allocateObject : 19 std::get<std::list<parser::AllocateObject>>(deallocateStmt.t)) { 20 std::visit( 21 common::visitors{ 22 [&](const parser::Name &name) { 23 auto const *symbol{name.symbol}; 24 if (context_.HasError(symbol)) { 25 // already reported an error 26 } else if (!IsVariableName(*symbol)) { 27 context_.Say(name.source, 28 "name in DEALLOCATE statement must be a variable name"_err_en_US); 29 } else if (!IsAllocatableOrPointer(*symbol)) { // C932 30 context_.Say(name.source, 31 "name in DEALLOCATE statement must have the ALLOCATABLE or POINTER attribute"_err_en_US); 32 } else { 33 context_.CheckIndexVarRedefine(name); 34 } 35 }, 36 [&](const parser::StructureComponent &structureComponent) { 37 // Only perform structureComponent checks it was successfully 38 // analyzed in expression analysis. 39 if (GetExpr(allocateObject)) { 40 if (!IsAllocatableOrPointer( 41 *structureComponent.component.symbol)) { // C932 42 context_.Say(structureComponent.component.source, 43 "component in DEALLOCATE statement must have the ALLOCATABLE or POINTER attribute"_err_en_US); 44 } 45 } 46 }, 47 }, 48 allocateObject.u); 49 } 50 bool gotStat{false}, gotMsg{false}; 51 for (const parser::StatOrErrmsg &deallocOpt : 52 std::get<std::list<parser::StatOrErrmsg>>(deallocateStmt.t)) { 53 std::visit( 54 common::visitors{ 55 [&](const parser::StatVariable &) { 56 if (gotStat) { 57 context_.Say( 58 "STAT may not be duplicated in a DEALLOCATE statement"_err_en_US); 59 } 60 gotStat = true; 61 }, 62 [&](const parser::MsgVariable &) { 63 if (gotMsg) { 64 context_.Say( 65 "ERRMSG may not be duplicated in a DEALLOCATE statement"_err_en_US); 66 } 67 gotMsg = true; 68 }, 69 }, 70 deallocOpt.u); 71 } 72 } 73 } // namespace Fortran::semantics 74