}
}
-bool IsValueDummy(const Symbol &symbol) {
- return IsDummy(symbol) && symbol.attrs().test(Attr::VALUE);
-}
-
bool IsPointerDummy(const Symbol &symbol) {
return IsPointer(symbol) && IsDummy(symbol);
}
// variable-name
bool IsVariableName(const Symbol &symbol) {
if (const Symbol * root{GetAssociationRoot(symbol)}) {
- return IsValueDummy(symbol) ||
- (root->has<ObjectEntityDetails>() && !IsParameter(*root) &&
- !IsIntentIn(*root));
+ return root->has<ObjectEntityDetails>() && !IsParameter(*root);
} else {
return false;
}
return nullptr;
}
-const Symbol *GetAssociatedVariable(const AssocEntityDetails &details) {
+static const Symbol *GetAssociatedVariable(const AssocEntityDetails &details) {
if (const MaybeExpr & expr{details.expr()}) {
if (evaluate::IsVariable(*expr)) {
if (const Symbol * varSymbol{evaluate::GetLastSymbol(*expr)}) {
// Return nullptr if the name is associated with an expression
const Symbol *GetAssociationRoot(const Symbol &symbol) {
const Symbol &ultimate{symbol.GetUltimate()};
- if (ultimate.has<AssocEntityDetails>()) { // construct association
- return GetAssociatedVariable(ultimate.get<AssocEntityDetails>());
+ if (const auto *details{ultimate.detailsIf<AssocEntityDetails>()}) {
+ // We have a construct association
+ return GetAssociatedVariable(*details);
} else {
return &ultimate;
}
if (const auto *details{root->detailsIf<ObjectEntityDetails>()}) {
if (const DeclTypeSpec * type{details->type()}) {
if (const DerivedTypeSpec * derived{type->AsDerived()}) {
- if (IsEventTypeOrLockType(derived) ||
- HasEventOrLockPotentialComponent(*derived)) {
- return true;
- }
+ return IsEventTypeOrLockType(derived) ||
+ HasEventOrLockPotentialComponent(*derived);
}
}
}
bool IsExternalInPureContext(const Symbol &symbol, const Scope &scope) {
if (const auto *pureProc{semantics::FindPureProcedureContaining(&scope)}) {
if (const Symbol * root{GetAssociationRoot(symbol)}) {
- if (semantics::FindExternallyVisibleObject(*root, *pureProc)) {
+ if (FindExternallyVisibleObject(*root, *pureProc)) {
return true;
}
}
return IsProtected(symbol) && !IsHostAssociated(symbol, currentScope);
}
+// C1101 and C1158
+// TODO Need to check for the case of a variable that has a vector subscript
+// that is construct associated, also need to check for a coindexed object
std::optional<parser::MessageFixedText> WhyNotModifiable(
const Symbol &symbol, const Scope &scope) {
const Symbol *root{GetAssociationRoot(symbol)};
} else if (InProtectedContext(*root, scope)) {
return "'%s' is protected in this scope"_en_US;
} else if (IsExternalInPureContext(*root, scope)) {
- return "'%s' is an external that is referenced in a PURE procedure"_en_US;
+ return "'%s' is externally visible and referenced in a PURE"
+ " procedure"_en_US;
} else if (IsOrContainsEventOrLockComponent(*root)) {
return "'%s' is an entity with either an EVENT_TYPE or LOCK_TYPE"_en_US;
- } else if (IsIntentIn(*root) && !IsValueDummy(*root)) {
+ } else if (IsIntentIn(*root)) {
return "'%s' is an INTENT(IN) dummy argument"_en_US;
} else if (!IsVariableName(*root)) {
return "'%s' is not a variable"_en_US;
}
}
-bool IsModifiable(const Symbol &symbol, const Scope &scope) {
- return !WhyNotModifiable(symbol, scope);
-}
-
static const DeclTypeSpec &InstantiateIntrinsicType(Scope &scope,
const DeclTypeSpec &spec, SemanticsContext &semanticsContext) {
const IntrinsicTypeSpec *intrinsic{spec.AsIntrinsic()};
const Symbol *FindInterface(const Symbol &);
const Symbol *FindSubprogram(const Symbol &);
const Symbol *FindFunctionResult(const Symbol &);
-const Symbol *GetAssociatedVariable(const AssocEntityDetails &);
const Symbol *GetAssociationRoot(const Symbol &);
bool IsCommonBlockContaining(const Symbol &block, const Symbol &object);
bool IsHostAssociated(const Symbol &, const Scope &);
bool IsDummy(const Symbol &);
bool IsPointerDummy(const Symbol &);
-bool IsValueDummy(const Symbol &);
bool IsFunction(const Symbol &);
bool IsPureProcedure(const Symbol &);
bool IsPureProcedure(const Scope &);
std::optional<parser::MessageFixedText> WhyNotModifiable(
const Symbol &symbol, const Scope &scope);
// Is the symbol modifiable in this scope
-bool IsModifiable(const Symbol &symbol, const Scope &scope);
bool IsExternalInPureContext(const Symbol &symbol, const Scope &scope);
// Returns the complete list of derived type parameter symbols in
use m3
! C857 This is not OK because of the "protected" attribute
-!ERROR: 'prot' must be able to appear in a variable definition context to appear in a locality-spec
+!ERROR: 'prot' may not appear in a locality-spec because it is not definable
do concurrent (i=1:5) local(prot)
end do
end do
! C1101 This is not OK because 'a' is not associated with a variable
-!ERROR: 'a' must be able to appear in a variable definition context to appear in a locality-spec
+!ERROR: 'a' may not appear in a locality-spec because it is not definable
do concurrent (i=1:5) local(a)
end do
end associate
select type ( a => func() )
type is ( point )
! C1158 This is not OK because 'a' is not associated with a variable
-!ERROR: 'a' must be able to appear in a variable definition context to appear in a locality-spec
+!ERROR: 'a' may not appear in a locality-spec because it is not definable
do concurrent (i=1:5) local(a)
end do
end select
use m4
! C1594 This is not OK because we're in a PURE subroutine
-!ERROR: 'var' must be able to appear in a variable definition context to appear in a locality-spec
+!ERROR: 'var' may not appear in a locality-spec because it is not definable
do concurrent (i=1:5) local(var)
end do
end subroutine s7
subroutine s8()
integer, parameter :: iconst = 343
-!ERROR: 'iconst' must be able to appear in a variable definition context to appear in a locality-spec
+!ERROR: 'iconst' may not appear in a locality-spec because it is not definable
do concurrent (i=1:5) local(iconst)
end do
end subroutine s8