[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:
Jean Perier 2019-07-26 08:11:59 -07:00
parent b08064ca1f
commit 0a9725607b
3 changed files with 40 additions and 38 deletions

View file

@ -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());
}
}
}

View file

@ -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();
}
}

View file

@ -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();