[flang] Fix handling of DataRef when analyzing CoindexedNamedObject
authorTim Keith <tkeith@nvidia.com>
Sat, 7 Mar 2020 01:05:04 +0000 (17:05 -0800)
committerTim Keith <tkeith@nvidia.com>
Tue, 10 Mar 2020 00:25:12 +0000 (17:25 -0700)
As we loop through the Components, maintain a pointer to the current
DataRef rather than moving it. This is more efficient and the previous
behavior caused illegal memory accesses.

Original-commit: flang-compiler/f18@cede2971ff863b8dd6a2c8727f6566a444ac7a52
Reviewed-on: https://github.com/flang-compiler/f18/pull/1050
Tree-same-pre-rewrite: false

flang/lib/Semantics/expression.cpp

index 2e13b21..dd016f9 100644 (file)
@@ -1023,22 +1023,23 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
-  if (auto dataRef{ExtractDataRef(Analyze(x.base))}) {
+  if (auto maybeDataRef{ExtractDataRef(Analyze(x.base))}) {
+    DataRef *dataRef{&*maybeDataRef};
     std::vector<Subscript> subscripts;
     SymbolVector reversed;
     if (auto *aRef{std::get_if<ArrayRef>(&dataRef->u)}) {
       subscripts = std::move(aRef->subscript());
       reversed.push_back(aRef->GetLastSymbol());
       if (Component * component{aRef->base().UnwrapComponent()}) {
-        *dataRef = std::move(component->base());
+        dataRef = &component->base();
       } else {
-        dataRef.reset();
+        dataRef = nullptr;
       }
     }
     if (dataRef) {
       while (auto *component{std::get_if<Component>(&dataRef->u)}) {
         reversed.push_back(component->GetLastSymbol());
-        *dataRef = std::move(component->base());
+        dataRef = &component->base();
       }
       if (auto *baseSym{std::get_if<SymbolRef>(&dataRef->u)}) {
         reversed.push_back(*baseSym);
@@ -2502,7 +2503,7 @@ bool ExpressionAnalyzer::EnforceTypeConstraint(parser::CharBlock at,
     const MaybeExpr &result, TypeCategory category, bool defaultKind) {
   if (result) {
     if (auto type{result->GetType()}) {
-      if (type->category() != category) { // C885
+      if (type->category() != category) {  // C885
         Say(at, "Must have %s type, but is %s"_err_en_US,
             ToUpperCase(EnumToString(category)),
             ToUpperCase(type->AsFortran()));