From 73f21db537f7828ab55bd2a365e5ccdf2c439ab7 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 28 Jan 2022 08:28:00 -0800 Subject: [PATCH] [flang] Fix: use right symbol for parent component When constructing the representation for a component reference to an inherited component, expression semantics make the parent component references explicit in the DataRef; e.g., base%component becomes base%parent%grandparent%component if component was inheritance-associated through two levels. But expression semantics was inserting references to the symbol table entries for the intermediate types, not the symbols for the parent components in the extended types. (We didn't notice the distinction until recently because both symbols have the same name; this only affects lowering.) Find and use the right symbols. Differential Revision: https://reviews.llvm.org/D118746 --- flang/include/flang/Semantics/symbol.h | 10 +++++----- flang/lib/Semantics/expression.cpp | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h index 19304d7..e96f259 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -665,6 +665,11 @@ public: // for a parameterized derived type instantiation with the instance's scope. const DerivedTypeSpec *GetParentTypeSpec(const Scope * = nullptr) const; + // If a derived type's symbol refers to an extended derived type, + // return the parent component's symbol. The scope of the derived type + // can be overridden. + const Symbol *GetParentComponent(const Scope * = nullptr) const; + SemanticsContext &GetSemanticsContext() const; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() const; @@ -686,11 +691,6 @@ private: friend llvm::raw_ostream &DumpForUnparse( llvm::raw_ostream &, const Symbol &, bool); - // If a derived type's symbol refers to an extended derived type, - // return the parent component's symbol. The scope of the derived type - // can be overridden. - const Symbol *GetParentComponent(const Scope * = nullptr) const; - template friend class Symbols; template friend class std::array; }; diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 56d3b82..d031993 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -987,11 +987,20 @@ std::optional ExpressionAnalyzer::CreateComponent( if (&component.owner() == &scope) { return Component{std::move(base), component}; } - if (const semantics::Scope * parentScope{scope.GetDerivedTypeParent()}) { - if (const Symbol * parentComponent{parentScope->GetSymbol()}) { - return CreateComponent( - DataRef{Component{std::move(base), *parentComponent}}, component, - *parentScope); + if (const Symbol * typeSymbol{scope.GetSymbol()}) { + if (const Symbol * + parentComponent{typeSymbol->GetParentComponent(&scope)}) { + if (const auto *object{ + parentComponent->detailsIf()}) { + if (const auto *parentType{object->type()}) { + if (const semantics::Scope * + parentScope{parentType->derivedTypeSpec().scope()}) { + return CreateComponent( + DataRef{Component{std::move(base), *parentComponent}}, + component, *parentScope); + } + } + } } } return std::nullopt; -- 2.7.4