Follow-up to PR175211. There are still a few AST nodes that don't have any of the standard traits (Wrapper/Tuple/etc). Because of that they require special handling in the parse tree visitor. Convert a subset of these nodes to the typical format, and remove the special cases from the parse tree visitor. The members of these nodes were frequently used, so instead of extracting them by hand each time use helper member functions to access them.
65 lines
2.6 KiB
C++
65 lines
2.6 KiB
C++
//===-- lib/Semantics/check-nullify.cpp -----------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "check-nullify.h"
|
|
#include "definable.h"
|
|
#include "flang/Evaluate/expression.h"
|
|
#include "flang/Parser/message.h"
|
|
#include "flang/Parser/parse-tree.h"
|
|
#include "flang/Semantics/expression.h"
|
|
#include "flang/Semantics/tools.h"
|
|
|
|
namespace Fortran::semantics {
|
|
|
|
void NullifyChecker::Leave(const parser::NullifyStmt &nullifyStmt) {
|
|
CHECK(context_.location());
|
|
const Scope &scope{context_.FindScope(*context_.location())};
|
|
for (const parser::PointerObject &pointerObject : nullifyStmt.v) {
|
|
common::visit(
|
|
common::visitors{
|
|
[&](const parser::Name &name) {
|
|
if (name.symbol) {
|
|
if (auto whyNot{WhyNotDefinable(name.source, scope,
|
|
DefinabilityFlags{DefinabilityFlag::PointerDefinition},
|
|
*name.symbol)}) {
|
|
context_.messages()
|
|
.Say(name.source,
|
|
"'%s' may not appear in NULLIFY"_err_en_US,
|
|
name.source)
|
|
.Attach(std::move(
|
|
whyNot->set_severity(parser::Severity::Because)));
|
|
}
|
|
}
|
|
},
|
|
[&](const parser::StructureComponent &structureComponent) {
|
|
const auto &component{structureComponent.Component()};
|
|
SourceName at{component.source};
|
|
if (const auto *checkedExpr{GetExpr(context_, pointerObject)}) {
|
|
if (auto whyNot{WhyNotDefinable(at, scope,
|
|
DefinabilityFlags{DefinabilityFlag::PointerDefinition},
|
|
*checkedExpr)}) {
|
|
context_.messages()
|
|
.Say(at, "'%s' may not appear in NULLIFY"_err_en_US, at)
|
|
.Attach(std::move(
|
|
whyNot->set_severity(parser::Severity::Because)));
|
|
}
|
|
}
|
|
},
|
|
},
|
|
pointerObject.u);
|
|
}
|
|
// From 9.7.3.1(1)
|
|
// A pointer-object shall not depend on the value,
|
|
// bounds, or association status of another pointer-
|
|
// object in the same NULLIFY statement.
|
|
// This restriction is the programmer's responsibility.
|
|
// Some dependencies can be found compile time or at
|
|
// runtime, but for now we choose to skip such checks.
|
|
}
|
|
} // namespace Fortran::semantics
|