Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions flang/include/flang/Evaluate/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -1417,8 +1417,8 @@ inline bool IsAssumedSizeArray(const Symbol &symbol) {
// In a SELECT RANK construct, ResolveAssociations() stops at a
// RANK(n) or RANK(*) case symbol, but traverses the selector for
// RANK DEFAULT.
const Symbol &ResolveAssociations(const Symbol &);
const Symbol &GetAssociationRoot(const Symbol &);
const Symbol &ResolveAssociations(const Symbol &, bool stopAtTypeGuard = false);
const Symbol &GetAssociationRoot(const Symbol &, bool stopAtTypeGuard = false);

const Symbol *FindCommonBlockContaining(const Symbol &);
int CountLenParameters(const DerivedTypeSpec &);
Expand Down
3 changes: 3 additions & 0 deletions flang/include/flang/Semantics/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,11 @@ class AssocEntityDetails : public EntityDetails {
}
bool IsAssumedSize() const { return rank_.value_or(0) == isAssumedSize; }
bool IsAssumedRank() const { return rank_.value_or(0) == isAssumedRank; }
bool isTypeGuard() const { return isTypeGuard_; }
void set_rank(int rank);
void set_IsAssumedSize();
void set_IsAssumedRank();
void set_isTypeGuard(bool yes = true);

private:
MaybeExpr expr_;
Expand All @@ -340,6 +342,7 @@ class AssocEntityDetails : public EntityDetails {
static constexpr int isAssumedSize{-1}; // RANK(*)
static constexpr int isAssumedRank{-2}; // RANK DEFAULT
std::optional<int> rank_;
bool isTypeGuard_{false}; // TYPE IS or CLASS IS, but not CLASS(DEFAULT)
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const AssocEntityDetails &);

Expand Down
10 changes: 6 additions & 4 deletions flang/lib/Evaluate/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,10 +1540,12 @@ bool CheckForCoindexedObject(parser::ContextualMessages &messages,

namespace Fortran::semantics {

const Symbol &ResolveAssociations(const Symbol &original) {
const Symbol &ResolveAssociations(
const Symbol &original, bool stopAtTypeGuard) {
const Symbol &symbol{original.GetUltimate()};
if (const auto *details{symbol.detailsIf<AssocEntityDetails>()}) {
if (!details->rank()) { // Not RANK(n) or RANK(*)
if (!details->rank() /* not RANK(n) or RANK(*) */ &&
!(stopAtTypeGuard && details->isTypeGuard())) {
if (const Symbol * nested{UnwrapWholeSymbolDataRef(details->expr())}) {
return ResolveAssociations(*nested);
}
Expand All @@ -1567,8 +1569,8 @@ static const Symbol *GetAssociatedVariable(const AssocEntityDetails &details) {
return nullptr;
}

const Symbol &GetAssociationRoot(const Symbol &original) {
const Symbol &symbol{ResolveAssociations(original)};
const Symbol &GetAssociationRoot(const Symbol &original, bool stopAtTypeGuard) {
const Symbol &symbol{ResolveAssociations(original, stopAtTypeGuard)};
if (const auto *details{symbol.detailsIf<AssocEntityDetails>()}) {
if (const Symbol * root{GetAssociatedVariable(*details)}) {
return *root;
Expand Down
6 changes: 3 additions & 3 deletions flang/lib/Semantics/check-call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,9 +535,6 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
if (actualLastSymbol) {
actualLastSymbol = &ResolveAssociations(*actualLastSymbol);
}
const ObjectEntityDetails *actualLastObject{actualLastSymbol
? actualLastSymbol->detailsIf<ObjectEntityDetails>()
: nullptr};
int actualRank{actualType.Rank()};
if (dummy.type.attrs().test(
characteristics::TypeAndShape::Attr::AssumedShape)) {
Expand Down Expand Up @@ -689,6 +686,9 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
}
}
const ObjectEntityDetails *actualLastObject{actualLastSymbol
? actualLastSymbol->detailsIf<ObjectEntityDetails>()
: nullptr};
if (actualLastObject && actualLastObject->IsCoarray() &&
dummy.attrs.test(characteristics::DummyDataObject::Attr::Allocatable) &&
dummy.intent == common::Intent::Out &&
Expand Down
14 changes: 7 additions & 7 deletions flang/lib/Semantics/check-do-forall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ class DoConcurrentBodyEnforce {
// of its components?
static bool MightDeallocatePolymorphic(const Symbol &original,
const std::function<bool(const Symbol &)> &WillDeallocate) {
const Symbol &symbol{ResolveAssociations(original)};
const Symbol &symbol{
ResolveAssociations(original, /*stopAtTypeGuard=*/true)};
// Check the entity itself, no coarray exception here
if (IsPolymorphicAllocatable(symbol)) {
return true;
Expand Down Expand Up @@ -182,11 +183,10 @@ class DoConcurrentBodyEnforce {
impure.name(), reason);
}

void SayDeallocateOfPolymorph(
void SayDeallocateOfPolymorphic(
parser::CharBlock location, const Symbol &entity, const char *reason) {
context_.SayWithDecl(entity, location,
"Deallocation of a polymorphic entity caused by %s"
" not allowed in DO CONCURRENT"_err_en_US,
"Deallocation of a polymorphic entity caused by %s not allowed in DO CONCURRENT"_err_en_US,
reason);
}

Expand All @@ -206,7 +206,7 @@ class DoConcurrentBodyEnforce {
const Symbol &entity{*pair.second};
if (IsAllocatable(entity) && !IsSaved(entity) &&
MightDeallocatePolymorphic(entity, DeallocateAll)) {
SayDeallocateOfPolymorph(endBlockStmt.source, entity, reason);
SayDeallocateOfPolymorphic(endBlockStmt.source, entity, reason);
}
if (const Symbol * impure{HasImpureFinal(entity)}) {
SayDeallocateWithImpureFinal(entity, reason, *impure);
Expand All @@ -222,7 +222,7 @@ class DoConcurrentBodyEnforce {
if (const Symbol * entity{GetLastName(variable).symbol}) {
const char *reason{"assignment"};
if (MightDeallocatePolymorphic(*entity, DeallocateNonCoarray)) {
SayDeallocateOfPolymorph(variable.GetSource(), *entity, reason);
SayDeallocateOfPolymorphic(variable.GetSource(), *entity, reason);
}
if (const auto *assignment{GetAssignment(stmt)}) {
const auto &lhs{assignment->lhs};
Expand Down Expand Up @@ -257,7 +257,7 @@ class DoConcurrentBodyEnforce {
const DeclTypeSpec *entityType{entity.GetType()};
if ((entityType && entityType->IsPolymorphic()) || // POINTER case
MightDeallocatePolymorphic(entity, DeallocateAll)) {
SayDeallocateOfPolymorph(
SayDeallocateOfPolymorphic(
currentStatementSourcePosition_, entity, reason);
}
if (const Symbol * impure{HasImpureFinal(entity)}) {
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3289,7 +3289,7 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) {
dyType && dyType->IsPolymorphic()) { // 10.2.1.2p1(1)
const Symbol *lastWhole0{UnwrapWholeSymbolOrComponentDataRef(lhs)};
const Symbol *lastWhole{
lastWhole0 ? &lastWhole0->GetUltimate() : nullptr};
lastWhole0 ? &ResolveAssociations(*lastWhole0) : nullptr};
if (!lastWhole || !IsAllocatable(*lastWhole)) {
Say("Left-hand side of assignment may not be polymorphic unless assignment is to an entire allocatable"_err_en_US);
} else if (evaluate::IsCoarray(*lastWhole)) {
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7771,6 +7771,7 @@ void ConstructVisitor::Post(const parser::TypeGuardStmt::Guard &x) {
SetTypeFromAssociation(*symbol);
} else if (const auto *type{GetDeclTypeSpec()}) {
symbol->SetType(*type);
symbol->get<AssocEntityDetails>().set_isTypeGuard();
}
SetAttrsFromAssociation(*symbol);
}
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Semantics/symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ void EntityDetails::set_type(const DeclTypeSpec &type) {
void AssocEntityDetails::set_rank(int rank) { rank_ = rank; }
void AssocEntityDetails::set_IsAssumedSize() { rank_ = isAssumedSize; }
void AssocEntityDetails::set_IsAssumedRank() { rank_ = isAssumedRank; }
void AssocEntityDetails::set_isTypeGuard(bool yes) { isTypeGuard_ = yes; }
void EntityDetails::ReplaceType(const DeclTypeSpec &type) { type_ = &type; }

ObjectEntityDetails::ObjectEntityDetails(EntityDetails &&d)
Expand Down
8 changes: 4 additions & 4 deletions flang/lib/Semantics/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,9 +633,9 @@ const EquivalenceSet *FindEquivalenceSet(const Symbol &symbol) {
}

bool IsOrContainsEventOrLockComponent(const Symbol &original) {
const Symbol &symbol{ResolveAssociations(original)};
if (const auto *details{symbol.detailsIf<ObjectEntityDetails>()}) {
if (const DeclTypeSpec * type{details->type()}) {
const Symbol &symbol{ResolveAssociations(original, /*stopAtTypeGuard=*/true)};
if (evaluate::IsVariable(symbol)) {
if (const DeclTypeSpec * type{symbol.GetType()}) {
if (const DerivedTypeSpec * derived{type->AsDerived()}) {
return IsEventTypeOrLockType(derived) ||
FindEventOrLockPotentialComponent(*derived);
Expand Down Expand Up @@ -849,7 +849,7 @@ static const Symbol *HasImpureFinal(
}

const Symbol *HasImpureFinal(const Symbol &original, std::optional<int> rank) {
const Symbol &symbol{ResolveAssociations(original)};
const Symbol &symbol{ResolveAssociations(original, /*stopAtTypeGuard=*/true)};
if (symbol.has<ObjectEntityDetails>()) {
if (const DeclTypeSpec * symType{symbol.GetType()}) {
if (const DerivedTypeSpec * derived{symType->AsDerived()}) {
Expand Down
12 changes: 12 additions & 0 deletions flang/test/Semantics/doconcurrent08.f90
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ subroutine s2()
class(Base), allocatable, codimension[:] :: allocPolyComponentVar
class(Base), allocatable, codimension[:] :: allocPolyComponentVar1

class(*), allocatable :: unlimitedPoly

allocate(ChildType :: localVar)
allocate(ChildType :: localVar1)
allocate(Base :: localVar2)
Expand Down Expand Up @@ -162,6 +164,16 @@ subroutine s2()
!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
allocPolyCoarray = allocPolyCoarray1

!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
unlimitedPoly = 1
select type (unlimitedPoly)
type is (integer)
unlimitedPoly = 1 ! ok
class default
!ERROR: Deallocation of a polymorphic entity caused by assignment not allowed in DO CONCURRENT
unlimitedPoly = 1
end select

end do
end subroutine s2

Expand Down