1 //===-- lib/Semantics/check-nullify.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-nullify.h" 10 #include "assignment.h" 11 #include "flang/Evaluate/expression.h" 12 #include "flang/Parser/message.h" 13 #include "flang/Parser/parse-tree.h" 14 #include "flang/Semantics/expression.h" 15 #include "flang/Semantics/tools.h" 16 17 namespace Fortran::semantics { 18 19 void NullifyChecker::Leave(const parser::NullifyStmt &nullifyStmt) { 20 CHECK(context_.location()); 21 const Scope &scope{context_.FindScope(*context_.location())}; 22 const Scope *pure{FindPureProcedureContaining(scope)}; 23 parser::ContextualMessages messages{ 24 *context_.location(), &context_.messages()}; 25 for (const parser::PointerObject &pointerObject : nullifyStmt.v) { 26 common::visit( 27 common::visitors{ 28 [&](const parser::Name &name) { 29 const Symbol *symbol{name.symbol}; 30 if (context_.HasError(symbol)) { 31 // already reported an error 32 } else if (!IsVariableName(*symbol) && 33 !IsProcedurePointer(*symbol)) { 34 messages.Say(name.source, 35 "name in NULLIFY statement must be a variable or procedure pointer"_err_en_US); 36 } else if (!IsPointer(*symbol)) { // C951 37 messages.Say(name.source, 38 "name in NULLIFY statement must have the POINTER attribute"_err_en_US); 39 } else if (pure) { 40 CheckDefinabilityInPureScope(messages, *symbol, scope, *pure); 41 } 42 }, 43 [&](const parser::StructureComponent &structureComponent) { 44 if (const auto *checkedExpr{GetExpr(context_, pointerObject)}) { 45 if (!IsPointer(*structureComponent.component.symbol)) { // C951 46 messages.Say(structureComponent.component.source, 47 "component in NULLIFY statement must have the POINTER attribute"_err_en_US); 48 } else if (pure) { 49 if (const Symbol * symbol{GetFirstSymbol(*checkedExpr)}) { 50 CheckDefinabilityInPureScope( 51 messages, *symbol, scope, *pure); 52 } 53 } 54 } 55 }, 56 }, 57 pointerObject.u); 58 } 59 // From 9.7.3.1(1) 60 // A pointer-object shall not depend on the value, 61 // bounds, or association status of another pointer- 62 // object in the same NULLIFY statement. 63 // This restriction is the programmer's responsibilty. 64 // Some dependencies can be found compile time or at 65 // runtime, but for now we choose to skip such checks. 66 } 67 } // namespace Fortran::semantics 68