[flang] Associate entities are variables
authorPeter Klausler <pklausler@nvidia.com>
Thu, 9 Feb 2023 18:00:12 +0000 (10:00 -0800)
committerPeter Klausler <pklausler@nvidia.com>
Tue, 14 Feb 2023 15:50:45 +0000 (07:50 -0800)
A more precise reading of the standard for associate entities, like "x"
in ASSOCIATE(x => selector), shows that the utility predicates used for
determining their status as variables should treat them as variables
(not necessarily definable), whatever the selector is.  Currently
the cases where the selector is an expression or a designator with a
vector subscript are not properly considered to be variables.
(See Fortran 2018, 11.1.3.3 paragraph 5.)

Differential Revision: https://reviews.llvm.org/D143835

flang/lib/Evaluate/tools.cpp

index bf530f8..a39493b 100644 (file)
@@ -78,8 +78,11 @@ std::optional<DataRef> ExtractSubstringBase(const Substring &substring) {
 // IsVariable()
 
 auto IsVariableHelper::operator()(const Symbol &symbol) const -> Result {
-  const Symbol &root{GetAssociationRoot(symbol)};
-  return !IsNamedConstant(root) && root.has<semantics::ObjectEntityDetails>();
+  // ASSOCIATE(x => expr) -- x counts as a variable, but undefinable
+  const Symbol &ultimate{symbol.GetUltimate()};
+  return !IsNamedConstant(ultimate) &&
+      (ultimate.has<semantics::ObjectEntityDetails>() ||
+          ultimate.has<semantics::AssocEntityDetails>());
 }
 auto IsVariableHelper::operator()(const Component &x) const -> Result {
   const Symbol &comp{x.GetLastSymbol()};
@@ -1263,15 +1266,10 @@ const Symbol *GetMainEntry(const Symbol *symbol) {
 }
 
 bool IsVariableName(const Symbol &original) {
-  const Symbol &symbol{ResolveAssociations(original)};
-  if (symbol.has<ObjectEntityDetails>()) {
-    return !IsNamedConstant(symbol);
-  } else if (const auto *assoc{symbol.detailsIf<AssocEntityDetails>()}) {
-    const auto &expr{assoc->expr()};
-    return expr && IsVariable(*expr) && !HasVectorSubscript(*expr);
-  } else {
-    return false;
-  }
+  const Symbol &ultimate{original.GetUltimate()};
+  return !IsNamedConstant(ultimate) &&
+      (ultimate.has<ObjectEntityDetails>() ||
+          ultimate.has<AssocEntityDetails>());
 }
 
 bool IsPureProcedure(const Symbol &original) {