[flang] Improve error messages about component types in allocate checks
Use component visitor framework to attach more information reagrding where is the ultimate/potential component that is forbidden. Also remove unused functions. Original-commit: flang-compiler/f18@4619c5860a Reviewed-on: https://github.com/flang-compiler/f18/pull/607 Tree-same-pre-rewrite: false
This commit is contained in:
parent
b08064ca1f
commit
0a9725607b
|
@ -119,13 +119,14 @@ static std::optional<AllocateCheckerInfo> CheckAllocateOptions(
|
|||
info.typeSpecLoc = parser::FindSourceLocation(*typeSpec);
|
||||
if (const DerivedTypeSpec * derived{info.typeSpec->AsDerived()}) {
|
||||
// C937
|
||||
if (const Symbol *
|
||||
coarrayComponent{HasCoarrayUltimateComponent(*derived)}) {
|
||||
if (auto coarraySearch{ComponentVisitor::HasCoarrayUltimate(*derived)}) {
|
||||
context
|
||||
.Say(
|
||||
"Type-spec in ALLOCATE must not specify a type with a coarray ultimate component"_err_en_US)
|
||||
.Attach(coarrayComponent->name(),
|
||||
"Coarray ultimate component declared here"_en_US);
|
||||
.Say("Type-spec in ALLOCATE must not specify a type with a coarray"
|
||||
" ultimate component"_err_en_US)
|
||||
.Attach(coarraySearch.Result()->name(),
|
||||
"Type '%s' has coarray ultimate component '%s' declared here"_en_US,
|
||||
info.typeSpec->AsFortran(),
|
||||
coarraySearch.BuildResultDesignatorName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,26 +207,31 @@ static std::optional<AllocateCheckerInfo> CheckAllocateOptions(
|
|||
const DerivedTypeSpec &derived{
|
||||
info.sourceExprType.value().GetDerivedTypeSpec()};
|
||||
// C949
|
||||
if (const Symbol *
|
||||
coarrayComponent{HasCoarrayUltimateComponent(derived)}) {
|
||||
if (auto coarraySearch{ComponentVisitor::HasCoarrayUltimate(derived)}) {
|
||||
context
|
||||
.Say(parserSourceExpr->source,
|
||||
"SOURCE or MOLD expression must not have a type with a coarray ultimate component"_err_en_US)
|
||||
.Attach(coarrayComponent->name(),
|
||||
"Coarray ultimate component declared here"_en_US);
|
||||
.Attach(coarraySearch.Result()->name(),
|
||||
"Type '%s' has coarray ultimate component '%s' declared here"_en_US,
|
||||
info.sourceExprType.value().AsFortran(),
|
||||
coarraySearch.BuildResultDesignatorName());
|
||||
}
|
||||
if (info.gotSrc) {
|
||||
// C948
|
||||
if (IsEventTypeOrLockType(&derived)) {
|
||||
context.Say(parserSourceExpr->source,
|
||||
"SOURCE expression type must not be EVENT_TYPE or LOCK_TYPE from ISO_FORTRAN_ENV"_err_en_US);
|
||||
} else if (const Symbol *
|
||||
component{HasEventOrLockPotentialComponent(derived)}) {
|
||||
} else if (auto componentSearch{
|
||||
ComponentVisitor::HasEventOrLockPotential(derived)}) {
|
||||
context
|
||||
.Say(parserSourceExpr->source,
|
||||
"SOURCE expression type must not have potential subobject component of type EVENT_TYPE or LOCK_TYPE from ISO_FORTRAN_ENV"_err_en_US)
|
||||
.Attach(component->name(),
|
||||
"Potential subobject component of forbidden type declared here"_en_US);
|
||||
"SOURCE expression type must not have potential subobject "
|
||||
"component"
|
||||
" of type EVENT_TYPE or LOCK_TYPE from ISO_FORTRAN_ENV"_err_en_US)
|
||||
.Attach(componentSearch.Result()->name(),
|
||||
"Type '%s' has potential ultimate component '%s' declared here"_en_US,
|
||||
info.sourceExprType.value().AsFortran(),
|
||||
componentSearch.BuildResultDesignatorName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -380,18 +380,6 @@ bool IsTeamType(const DerivedTypeSpec *derived) {
|
|||
return IsDerivedTypeFromModule(derived, "iso_fortran_env", "team_type");
|
||||
}
|
||||
|
||||
const Symbol *FindUltimateComponent(const DerivedTypeSpec &derivedTypeSpec,
|
||||
std::function<bool(const Symbol &)> predicate) {
|
||||
return ComponentVisitor{std::move(predicate)}
|
||||
.VisitUltimateComponents(derivedTypeSpec)
|
||||
.Result();
|
||||
}
|
||||
|
||||
const Symbol *HasCoarrayUltimateComponent(
|
||||
const DerivedTypeSpec &derivedTypeSpec) {
|
||||
return FindUltimateComponent(derivedTypeSpec, IsCoarray);
|
||||
}
|
||||
|
||||
const bool IsEventTypeOrLockType(const DerivedTypeSpec *derivedTypeSpec) {
|
||||
return IsDerivedTypeFromModule(
|
||||
derivedTypeSpec, "iso_fortran_env", "event_type") ||
|
||||
|
@ -412,7 +400,7 @@ bool IsOrContainsEventOrLockComponent(const Symbol &symbol) {
|
|||
if (const DeclTypeSpec * type{details->type()}) {
|
||||
if (const DerivedTypeSpec * derived{type->AsDerived()}) {
|
||||
return IsEventTypeOrLockType(derived) ||
|
||||
HasEventOrLockPotentialComponent(*derived);
|
||||
ComponentVisitor::HasEventOrLockPotential(*derived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -420,13 +408,6 @@ bool IsOrContainsEventOrLockComponent(const Symbol &symbol) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const Symbol *HasEventOrLockPotentialComponent(
|
||||
const DerivedTypeSpec &derivedTypeSpec) {
|
||||
return ComponentVisitor{IsEventTypeOrLockTypeObjectEntity}
|
||||
.VisitPotentialComponents(derivedTypeSpec)
|
||||
.Result();
|
||||
}
|
||||
|
||||
bool IsFinalizable(const Symbol &symbol) {
|
||||
if (const DeclTypeSpec * type{symbol.GetType()}) {
|
||||
if (const DerivedTypeSpec * derived{type->AsDerived()}) {
|
||||
|
@ -884,6 +865,12 @@ ComponentVisitor &ComponentVisitor::VisitDirectComponents(
|
|||
return *this;
|
||||
}
|
||||
|
||||
ComponentVisitor ComponentVisitor::HasEventOrLockPotential(
|
||||
const DerivedTypeSpec &derived) {
|
||||
return ComponentVisitor{IsEventTypeOrLockTypeObjectEntity}
|
||||
.VisitPotentialComponents(derived);
|
||||
}
|
||||
|
||||
std::string ComponentVisitor::BuildResultDesignatorName() const {
|
||||
std::string designator{""};
|
||||
for (const Symbol *component : componentStack_) {
|
||||
|
@ -892,4 +879,11 @@ std::string ComponentVisitor::BuildResultDesignatorName() const {
|
|||
return designator;
|
||||
}
|
||||
|
||||
const Symbol *FindUltimateComponent(const DerivedTypeSpec &derived,
|
||||
std::function<bool(const Symbol &)> predicate) {
|
||||
return ComponentVisitor{std::move(predicate)}
|
||||
.VisitUltimateComponents(derived)
|
||||
.Result();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,8 +78,6 @@ const bool IsEventTypeOrLockType(const DerivedTypeSpec *);
|
|||
// does not really matter for the checks where it is needed.
|
||||
const Symbol *HasCoarrayUltimateComponent(const DerivedTypeSpec &);
|
||||
// Same logic as HasCoarrayUltimateComponent, but looking for
|
||||
// potential component of EVENT_TYPE or LOCK_TYPE from
|
||||
// ISO_FORTRAN_ENV module.
|
||||
const Symbol *HasEventOrLockPotentialComponent(const DerivedTypeSpec &);
|
||||
bool IsOrContainsEventOrLockComponent(const Symbol &);
|
||||
|
||||
|
@ -236,10 +234,14 @@ public:
|
|||
ComponentVisitor &VisitUltimateComponents(const DerivedTypeSpec &);
|
||||
ComponentVisitor &VisitDirectComponents(const DerivedTypeSpec &);
|
||||
|
||||
// predefined common tests
|
||||
// Predefined common tests
|
||||
// Look for an ultimate component that is a coarray.
|
||||
static ComponentVisitor HasCoarrayUltimate(const DerivedTypeSpec &derived) {
|
||||
return ComponentVisitor{IsCoarray}.VisitUltimateComponents(derived);
|
||||
}
|
||||
// Look for a potential component of EVENT_TYPE or LOCK_TYPE from
|
||||
// ISO_FORTRAN_ENV module.
|
||||
static ComponentVisitor HasEventOrLockPotential(const DerivedTypeSpec &);
|
||||
|
||||
const Symbol *Result() const {
|
||||
return componentStack_.empty() ? nullptr : componentStack_.back();
|
||||
|
|
Loading…
Reference in a new issue