diff --git a/flang/include/flang/Evaluate/initial-image.h b/flang/include/flang/Evaluate/initial-image.h --- a/flang/include/flang/Evaluate/initial-image.h +++ b/flang/include/flang/Evaluate/initial-image.h @@ -30,6 +30,7 @@ }; explicit InitialImage(std::size_t bytes) : data_(bytes) {} + InitialImage(InitialImage &&that) = default; std::size_t size() const { return data_.size(); } @@ -93,19 +94,17 @@ void AddPointer(ConstantSubscript, const Expr &); - void Incorporate(ConstantSubscript, const InitialImage &); + void Incorporate(ConstantSubscript toOffset, const InitialImage &from, + ConstantSubscript fromOffset, ConstantSubscript bytes); // Conversions to constant initializers std::optional> AsConstant(FoldingContext &, const DynamicType &, const ConstantSubscripts &, ConstantSubscript offset = 0) const; - std::optional> AsConstantDataPointer( - const DynamicType &, ConstantSubscript offset = 0) const; - const ProcedureDesignator &AsConstantProcPointer( + std::optional> AsConstantPointer( ConstantSubscript offset = 0) const; friend class AsConstantHelper; - friend class AsConstantDataPointerHelper; private: std::vector data_; diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -41,6 +41,8 @@ std::optional substringStart, parser::CharBlock source) : symbol{symbol}, subscripts{subscripts}, substringStart{substringStart}, source{source} {} + explicit EquivalenceObject(Symbol &symbol) + : symbol{symbol}, source{symbol.name()} {} bool operator==(const EquivalenceObject &) const; bool operator<(const EquivalenceObject &) const; diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -497,6 +497,7 @@ LocalityShared, // named in SHARED locality-spec InDataStmt, // initialized in a DATA statement InNamelist, // flag is set if the symbol is in Namelist statement + CompilerCreated, // OpenACC data-sharing attribute AccPrivate, AccFirstPrivate, AccShared, // OpenACC data-mapping attribute @@ -779,7 +780,7 @@ } }; -// Symbol comparison is based on the order of cooked source +// Symbol comparison is usually based on the order of cooked source // stream creation and, when both are from the same cooked source, // their positions in that cooked source stream. // Don't use this comparator or OrderedSymbolSet to hold @@ -791,12 +792,17 @@ bool operator()(const MutableSymbolRef &, const MutableSymbolRef &) const; }; +struct SymbolOffsetCompare { + bool operator()(const SymbolRef &, const SymbolRef &) const; + bool operator()(const MutableSymbolRef &, const MutableSymbolRef &) const; +}; + using UnorderedSymbolSet = std::set; -using OrderedSymbolSet = std::set; +using SourceOrderedSymbolSet = std::set; template -OrderedSymbolSet OrderBySourcePosition(const A &container) { - OrderedSymbolSet result; +SourceOrderedSymbolSet OrderBySourcePosition(const A &container) { + SourceOrderedSymbolSet result; for (SymbolRef x : container) { result.emplace(x); } diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -56,6 +56,8 @@ const DeclTypeSpec *FindParentTypeSpec(const Scope &); const DeclTypeSpec *FindParentTypeSpec(const Symbol &); +const EquivalenceSet *FindEquivalenceSet(const Symbol &); + enum class Tristate { No, Yes, Maybe }; inline Tristate ToTristate(bool x) { return x ? Tristate::Yes : Tristate::No; } @@ -105,14 +107,13 @@ bool IsOrContainsEventOrLockComponent(const Symbol &); bool CanBeTypeBoundProc(const Symbol *); // Does a non-PARAMETER symbol have explicit initialization with =value or -// =>target in its declaration, or optionally in a DATA statement? (Being +// =>target in its declaration (but not in a DATA statement)? (Being // ALLOCATABLE or having a derived type with default component initialization // doesn't count; it must be a variable initialization that implies the SAVE // attribute, or a derived type component default value.) -bool IsStaticallyInitialized(const Symbol &, bool ignoreDATAstatements = false); +bool HasDeclarationInitializer(const Symbol &); // Is the symbol explicitly or implicitly initialized in any way? -bool IsInitialized(const Symbol &, bool ignoreDATAstatements = false, - const Symbol *derivedType = nullptr); +bool IsInitialized(const Symbol &, bool ignoreDATAstatements = false); // Is the symbol a component subject to deallocation or finalization? bool IsDestructible(const Symbol &, const Symbol *derivedType = nullptr); bool HasIntrinsicTypeName(const Symbol &); @@ -330,6 +331,13 @@ ProcedureDefinitionClass ClassifyProcedure(const Symbol &); +// Returns a list of storage associations due to EQUIVALENCE in a +// scope; each storage association is a list of symbol references +// in ascending order of scope offset. Note that the scope may have +// more EquivalenceSets than this function's result has storage +// associations; these are closures over equivalences. +std::list> GetStorageAssociations(const Scope &); + // Derived type component iterator that provides a C++ LegacyForwardIterator // iterator over the Ordered, Direct, Ultimate or Potential components of a // DerivedTypeSpec. These iterators can be used with STL algorithms diff --git a/flang/lib/Evaluate/initial-image.cpp b/flang/lib/Evaluate/initial-image.cpp --- a/flang/lib/Evaluate/initial-image.cpp +++ b/flang/lib/Evaluate/initial-image.cpp @@ -54,11 +54,14 @@ pointers_.emplace(offset, pointer); } -void InitialImage::Incorporate( - ConstantSubscript offset, const InitialImage &that) { - CHECK(that.pointers_.empty()); // pointers are not allowed in EQUIVALENCE - CHECK(offset + that.size() <= size()); - std::memcpy(&data_[offset], &that.data_[0], that.size()); +void InitialImage::Incorporate(ConstantSubscript toOffset, + const InitialImage &from, ConstantSubscript fromOffset, + ConstantSubscript bytes) { + CHECK(from.pointers_.empty()); // pointers are not allowed in EQUIVALENCE + CHECK(fromOffset >= 0 && bytes >= 0 && + static_cast(fromOffset + bytes) <= from.size()); + CHECK(static_cast(toOffset + bytes) <= size()); + std::memcpy(&data_[toOffset], &from.data_[fromOffset], bytes); } // Classes used with common::SearchTypes() to (re)construct Constant<> values @@ -97,26 +100,31 @@ const semantics::DerivedTypeSpec &derived{type_.GetDerivedTypeSpec()}; for (auto iter : DEREF(derived.scope())) { const Symbol &component{*iter.second}; - bool isPointer{IsPointer(component)}; - if (component.has() || - component.has()) { - auto componentType{DynamicType::From(component)}; - CHECK(componentType); + bool isProcPtr{IsProcedurePointer(component)}; + if (isProcPtr || component.has()) { auto at{offset_ + component.offset()}; - if (isPointer) { + if (isProcPtr) { for (std::size_t j{0}; j < elements; ++j, at += stride) { - Result value{image_.AsConstantDataPointer(*componentType, at)}; - CHECK(value); - typedValue[j].emplace(component, std::move(*value)); + if (Result value{image_.AsConstantPointer(at)}) { + typedValue[j].emplace(component, std::move(*value)); + } + } + } else if (IsPointer(component)) { + for (std::size_t j{0}; j < elements; ++j, at += stride) { + if (Result value{image_.AsConstantPointer(at)}) { + typedValue[j].emplace(component, std::move(*value)); + } } } else { + auto componentType{DynamicType::From(component)}; + CHECK(componentType.has_value()); auto componentExtents{GetConstantExtents(context_, component)}; - CHECK(componentExtents); + CHECK(componentExtents.has_value()); for (std::size_t j{0}; j < elements; ++j, at += stride) { - Result value{image_.AsConstant( - context_, *componentType, *componentExtents, at)}; - CHECK(value); - typedValue[j].emplace(component, std::move(*value)); + if (Result value{image_.AsConstant( + context_, *componentType, *componentExtents, at)}) { + typedValue[j].emplace(component, std::move(*value)); + } } } } @@ -159,45 +167,11 @@ AsConstantHelper{context, type, extents, *this, offset}); } -class AsConstantDataPointerHelper { -public: - using Result = std::optional>; - using Types = AllTypes; - AsConstantDataPointerHelper(const DynamicType &type, - const InitialImage &image, ConstantSubscript offset = 0) - : type_{type}, image_{image}, offset_{offset} {} - template Result Test() { - if (T::category != type_.category()) { - return std::nullopt; - } - if constexpr (T::category != TypeCategory::Derived) { - if (T::kind != type_.kind()) { - return std::nullopt; - } - } - auto iter{image_.pointers_.find(offset_)}; - if (iter == image_.pointers_.end()) { - return AsGenericExpr(NullPointer{}); - } - return iter->second; - } - -private: - const DynamicType &type_; - const InitialImage &image_; - ConstantSubscript offset_; -}; - -std::optional> InitialImage::AsConstantDataPointer( - const DynamicType &type, ConstantSubscript offset) const { - return common::SearchTypes(AsConstantDataPointerHelper{type, *this, offset}); -} - -const ProcedureDesignator &InitialImage::AsConstantProcPointer( +std::optional> InitialImage::AsConstantPointer( ConstantSubscript offset) const { - auto iter{pointers_.find(0)}; - CHECK(iter != pointers_.end()); - return DEREF(std::get_if(&iter->second.u)); + auto iter{pointers_.find(offset)}; + return iter == pointers_.end() ? std::optional>{} + : iter->second; } } // namespace Fortran::evaluate diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -526,7 +526,7 @@ messages_.Say("OPTIONAL attribute may apply only to a dummy " "argument"_err_en_US); // C849 } - if (IsStaticallyInitialized(symbol, true /* ignore DATA inits */)) { // C808 + if (HasDeclarationInitializer(symbol)) { // C808; ignore DATA initialization CheckPointerInitialization(symbol); if (IsAutomatic(symbol)) { messages_.Say( diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp --- a/flang/lib/Semantics/compute-offsets.cpp +++ b/flang/lib/Semantics/compute-offsets.cpp @@ -38,9 +38,9 @@ }; struct SymbolAndOffset { SymbolAndOffset(Symbol &s, std::size_t off, const EquivalenceObject &obj) - : symbol{&s}, offset{off}, object{&obj} {} + : symbol{s}, offset{off}, object{&obj} {} SymbolAndOffset(const SymbolAndOffset &) = default; - Symbol *symbol; + MutableSymbolRef symbol; std::size_t offset; const EquivalenceObject *object; }; diff --git a/flang/lib/Semantics/data-to-inits.h b/flang/lib/Semantics/data-to-inits.h --- a/flang/lib/Semantics/data-to-inits.h +++ b/flang/lib/Semantics/data-to-inits.h @@ -28,8 +28,9 @@ struct SymbolDataInitialization { using Range = common::Interval; explicit SymbolDataInitialization(std::size_t bytes) : image{bytes} {} + SymbolDataInitialization(SymbolDataInitialization &&) = default; evaluate::InitialImage image; - std::list inits; + std::list initializedRanges; }; using DataInitializations = std::map; diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp --- a/flang/lib/Semantics/data-to-inits.cpp +++ b/flang/lib/Semantics/data-to-inits.cpp @@ -20,6 +20,16 @@ #include "flang/Evaluate/tools.h" #include "flang/Semantics/tools.h" +// The job of generating explicit static initializers for objects that don't +// have them in order to implement default component initialization is now being +// done in lowering, so don't do it here in semantics; but the code remains here +// in case we change our minds. +static constexpr bool makeDefaultInitializationExplicit{false}; + +// Whether to delete the original "init()" initializers from storage-associated +// objects and pointers. +static constexpr bool removeOriginalInits{false}; + namespace Fortran::semantics { // Steps through a list of values in a DATA statement set; implements @@ -269,8 +279,10 @@ } }}; const auto GetImage{[&]() -> evaluate::InitialImage & { - auto &symbolInit{inits_.emplace(&symbol, symbol.size()).first->second}; - symbolInit.inits.emplace_back(offsetSymbol.offset(), offsetSymbol.size()); + auto iter{inits_.emplace(&symbol, symbol.size())}; + auto &symbolInit{iter.first->second}; + symbolInit.initializedRanges.emplace_back( + offsetSymbol.offset(), offsetSymbol.size()); return symbolInit.image; }}; const auto OutOfRangeError{[&]() { @@ -393,146 +405,422 @@ } } -static bool CombineSomeEquivalencedInits( - DataInitializations &inits, evaluate::ExpressionAnalyzer &exprAnalyzer) { - auto end{inits.end()}; - for (auto iter{inits.begin()}; iter != end; ++iter) { - const Symbol &symbol{*iter->first}; - Scope &scope{const_cast(symbol.owner())}; - if (scope.equivalenceSets().empty()) { - continue; // no problem to solve here - } - const auto *commonBlock{FindCommonBlockContaining(symbol)}; - // Sweep following DATA initializations in search of overlapping - // objects, accumulating into a vector; iterate to a fixed point. - std::vector conflicts; - auto minStart{symbol.offset()}; - auto maxEnd{symbol.offset() + symbol.size()}; - std::size_t minElementBytes{1}; - while (true) { - auto prevCount{conflicts.size()}; - conflicts.clear(); - for (auto scan{iter}; ++scan != end;) { - const Symbol &other{*scan->first}; - const Scope &otherScope{other.owner()}; - if (&otherScope == &scope && - FindCommonBlockContaining(other) == commonBlock && - maxEnd > other.offset() && - other.offset() + other.size() > minStart) { - // "other" conflicts with "symbol" or another conflict - conflicts.push_back(&other); - minStart = std::min(minStart, other.offset()); - maxEnd = std::max(maxEnd, other.offset() + other.size()); +// Looks for default derived type component initialization -- but +// *not* allocatables. +static const DerivedTypeSpec *HasDefaultInitialization(const Symbol &symbol) { + if (const auto *object{symbol.detailsIf()}) { + if (object->init().has_value()) { + return nullptr; // init is explicit, not default + } else if (!object->isDummy() && object->type()) { + if (const DerivedTypeSpec * derived{object->type()->AsDerived()}) { + DirectComponentIterator directs{*derived}; + if (std::find_if( + directs.begin(), directs.end(), [](const Symbol &component) { + return !IsAllocatable(component) && + HasDeclarationInitializer(component); + })) { + return derived; } } - if (conflicts.size() == prevCount) { - break; + } + } + return nullptr; +} + +// PopulateWithComponentDefaults() adds initializations to an instance +// of SymbolDataInitialization containing all of the default component +// initializers + +static void PopulateWithComponentDefaults(SymbolDataInitialization &init, + std::size_t offset, const DerivedTypeSpec &derived, + evaluate::FoldingContext &foldingContext); + +static void PopulateWithComponentDefaults(SymbolDataInitialization &init, + std::size_t offset, const DerivedTypeSpec &derived, + evaluate::FoldingContext &foldingContext, const Symbol &symbol) { + if (auto extents{evaluate::GetConstantExtents(foldingContext, symbol)}) { + const Scope &scope{derived.scope() ? *derived.scope() + : DEREF(derived.typeSymbol().scope())}; + std::size_t stride{scope.size()}; + if (std::size_t alignment{scope.alignment().value_or(0)}) { + stride = ((stride + alignment - 1) / alignment) * alignment; + } + for (auto elements{evaluate::GetSize(*extents)}; elements-- > 0; + offset += stride) { + PopulateWithComponentDefaults(init, offset, derived, foldingContext); + } + } +} + +// F'2018 19.5.3(10) allows storage-associated default component initialization +// when the values are identical. +static void PopulateWithComponentDefaults(SymbolDataInitialization &init, + std::size_t offset, const DerivedTypeSpec &derived, + evaluate::FoldingContext &foldingContext) { + const Scope &scope{ + derived.scope() ? *derived.scope() : DEREF(derived.typeSymbol().scope())}; + for (const auto &pair : scope) { + const Symbol &component{*pair.second}; + std::size_t componentOffset{offset + component.offset()}; + if (const auto *object{component.detailsIf()}) { + if (!IsAllocatable(component) && !IsAutomatic(component)) { + bool initialized{false}; + if (object->init()) { + initialized = true; + if (IsPointer(component)) { + if (auto extant{init.image.AsConstantPointer(componentOffset)}) { + initialized = !(*extant == *object->init()); + } + if (initialized) { + init.image.AddPointer(componentOffset, *object->init()); + } + } else { // data, not pointer + if (auto dyType{evaluate::DynamicType::From(component)}) { + if (auto extents{evaluate::GetConstantExtents( + foldingContext, component)}) { + if (auto extant{init.image.AsConstant( + foldingContext, *dyType, *extents, componentOffset)}) { + initialized = !(*extant == *object->init()); + } + } + } + if (initialized) { + init.image.Add(componentOffset, component.size(), *object->init(), + foldingContext); + } + } + } else if (const DeclTypeSpec * type{component.GetType()}) { + if (const DerivedTypeSpec * componentDerived{type->AsDerived()}) { + PopulateWithComponentDefaults(init, componentOffset, + *componentDerived, foldingContext, component); + } + } + if (initialized) { + init.initializedRanges.emplace_back( + componentOffset, component.size()); + } + } + } else if (const auto *proc{component.detailsIf()}) { + if (proc->init() && *proc->init()) { + SomeExpr procPtrInit{evaluate::ProcedureDesignator{**proc->init()}}; + auto extant{init.image.AsConstantPointer(componentOffset)}; + if (!extant || !(*extant == procPtrInit)) { + init.initializedRanges.emplace_back( + componentOffset, component.size()); + init.image.AddPointer(componentOffset, std::move(procPtrInit)); + } } } - if (conflicts.empty()) { - continue; - } - // Compute the minimum common granularity - if (auto dyType{evaluate::DynamicType::From(symbol)}) { - minElementBytes = evaluate::ToInt64( - dyType->MeasureSizeInBytes(exprAnalyzer.GetFoldingContext(), true)) - .value_or(1); - } - for (const Symbol *s : conflicts) { - if (auto dyType{evaluate::DynamicType::From(*s)}) { - minElementBytes = std::min(minElementBytes, - evaluate::ToInt64(dyType->MeasureSizeInBytes( - exprAnalyzer.GetFoldingContext(), true)) - .value_or(1)); + } +} + +static bool CheckForOverlappingInitialization( + const std::list &symbols, + SymbolDataInitialization &initialization, + evaluate::ExpressionAnalyzer &exprAnalyzer, const std::string &what) { + bool result{true}; + auto &context{exprAnalyzer.GetFoldingContext()}; + initialization.initializedRanges.sort(); + ConstantSubscript next{0}; + for (const auto &range : initialization.initializedRanges) { + if (range.start() < next) { + result = false; // error: overlap + bool hit{false}; + for (const Symbol &symbol : symbols) { + auto offset{range.start() - + static_cast( + symbol.offset() - symbols.front()->offset())}; + if (offset >= 0) { + if (auto badDesignator{evaluate::OffsetToDesignator( + context, symbol, offset, range.size())}) { + hit = true; + exprAnalyzer.Say(symbol.name(), + "%s affect '%s' more than once"_err_en_US, what, + badDesignator->AsFortran()); + } + } + } + CHECK(hit); + } + next = range.start() + range.size(); + CHECK(next <= static_cast(initialization.image.size())); + } + return result; +} + +static void IncorporateExplicitInitialization( + SymbolDataInitialization &combined, DataInitializations &inits, + const Symbol &symbol, ConstantSubscript firstOffset, + evaluate::FoldingContext &foldingContext) { + auto iter{inits.find(&symbol)}; + const auto offset{symbol.offset() - firstOffset}; + if (iter != inits.end()) { // DATA statement initialization + for (const auto &range : iter->second.initializedRanges) { + auto at{offset + range.start()}; + combined.initializedRanges.emplace_back(at, range.size()); + combined.image.Incorporate( + at, iter->second.image, range.start(), range.size()); + } + if (removeOriginalInits) { + inits.erase(iter); + } + } else { // Declaration initialization + Symbol &mutableSymbol{const_cast(symbol)}; + if (IsPointer(mutableSymbol)) { + if (auto *object{mutableSymbol.detailsIf()}) { + if (object->init()) { + combined.initializedRanges.emplace_back(offset, mutableSymbol.size()); + combined.image.AddPointer(offset, *object->init()); + if (removeOriginalInits) { + object->init().reset(); + } + } + } else if (auto *proc{mutableSymbol.detailsIf()}) { + if (proc->init() && *proc->init()) { + combined.initializedRanges.emplace_back(offset, mutableSymbol.size()); + combined.image.AddPointer( + offset, SomeExpr{evaluate::ProcedureDesignator{**proc->init()}}); + if (removeOriginalInits) { + proc->init().reset(); + } + } + } + } else if (auto *object{mutableSymbol.detailsIf()}) { + if (!IsNamedConstant(mutableSymbol) && object->init()) { + combined.initializedRanges.emplace_back(offset, mutableSymbol.size()); + combined.image.Add( + offset, mutableSymbol.size(), *object->init(), foldingContext); + if (removeOriginalInits) { + object->init().reset(); + } + } + } + } +} + +// Finds the size of the smallest element type in a list of +// storage-associated objects. +static std::size_t ComputeMinElementBytes( + const std::list &associated, + evaluate::FoldingContext &foldingContext) { + std::size_t minElementBytes{1}; + const Symbol &first{*associated.front()}; + for (const Symbol &s : associated) { + if (auto dyType{evaluate::DynamicType::From(s)}) { + auto size{static_cast( + evaluate::ToInt64(dyType->MeasureSizeInBytes(foldingContext, true)) + .value_or(1))}; + if (std::size_t alignment{dyType->GetAlignment(foldingContext)}) { + size = ((size + alignment - 1) / alignment) * alignment; + } + if (&s == &first) { + minElementBytes = size; } else { - minElementBytes = 1; + minElementBytes = std::min(minElementBytes, size); } + } else { + minElementBytes = 1; } - CHECK(minElementBytes > 0); - CHECK((minElementBytes & (minElementBytes - 1)) == 0); - auto bytes{static_cast(maxEnd - minStart)}; - CHECK(bytes % minElementBytes == 0); - const DeclTypeSpec &typeSpec{scope.MakeNumericType( - TypeCategory::Integer, KindExpr{minElementBytes})}; - // Combine "symbol" and "conflicts[]" into a compiler array temp - // that overlaps all of them, and merge their initial values into - // the temp's initializer. + } + return minElementBytes; +} + +// Checks for overlapping initialization errors in a list of +// storage-associated objects. Default component initializations +// are allowed to be overridden by explicit initializations. +// If the objects are static, save the combined initializer as +// a compiler-created object that covers all of them. +static bool CombineEquivalencedInitialization( + const std::list &associated, + evaluate::ExpressionAnalyzer &exprAnalyzer, DataInitializations &inits) { + // Compute the minimum common granularity and total size + const Symbol &first{*associated.front()}; + std::size_t maxLimit{0}; + for (const Symbol &s : associated) { + CHECK(s.offset() >= first.offset()); + auto limit{s.offset() + s.size()}; + if (limit > maxLimit) { + maxLimit = limit; + } + } + auto bytes{static_cast(maxLimit - first.offset())}; + Scope &scope{const_cast(first.owner())}; + // Combine the initializations of the associated objects. + // Apply all default initializations first. + SymbolDataInitialization combined{static_cast(bytes)}; + auto &foldingContext{exprAnalyzer.GetFoldingContext()}; + for (const Symbol &s : associated) { + if (!IsNamedConstant(s)) { + if (const auto *derived{HasDefaultInitialization(s)}) { + PopulateWithComponentDefaults( + combined, s.offset() - first.offset(), *derived, foldingContext, s); + } + } + } + if (!CheckForOverlappingInitialization(associated, combined, exprAnalyzer, + "Distinct default component initializations of equivalenced objects"s)) { + return false; + } + // Don't complain about overlap between explicit initializations and + // default initializations. + combined.initializedRanges.clear(); + // Now overlay all explicit initializations from DATA statements and + // from initializers in declarations. + for (const Symbol &symbol : associated) { + IncorporateExplicitInitialization( + combined, inits, symbol, first.offset(), foldingContext); + } + if (!CheckForOverlappingInitialization(associated, combined, exprAnalyzer, + "Explicit initializations of equivalenced objects"s)) { + return false; + } + // If the items are in static storage, save the final initialization. + if (std::find_if(associated.begin(), associated.end(), + [](SymbolRef ref) { return IsSaved(*ref); }) != associated.end()) { + // Create a compiler array temp that overlaps all the items. SourceName name{exprAnalyzer.context().GetTempName(scope)}; auto emplaced{ scope.try_emplace(name, Attrs{Attr::SAVE}, ObjectEntityDetails{})}; CHECK(emplaced.second); Symbol &combinedSymbol{*emplaced.first->second}; + combinedSymbol.set(Symbol::Flag::CompilerCreated); + inits.emplace(&combinedSymbol, std::move(combined)); auto &details{combinedSymbol.get()}; - combinedSymbol.set_offset(minStart); + combinedSymbol.set_offset(first.offset()); combinedSymbol.set_size(bytes); + std::size_t minElementBytes{ + ComputeMinElementBytes(associated, foldingContext)}; + if (!evaluate::IsValidKindOfIntrinsicType( + TypeCategory::Integer, minElementBytes) || + (bytes % minElementBytes) != 0) { + minElementBytes = 1; + } + const DeclTypeSpec &typeSpec{scope.MakeNumericType( + TypeCategory::Integer, KindExpr{minElementBytes})}; details.set_type(typeSpec); ArraySpec arraySpec; arraySpec.emplace_back(ShapeSpec::MakeExplicit(Bound{ bytes / static_cast(minElementBytes)})); details.set_shape(arraySpec); - if (commonBlock) { + if (const auto *commonBlock{FindCommonBlockContaining(first)}) { details.set_commonBlock(*commonBlock); } - // Merge these EQUIVALENCE'd DATA initializations, and remove the - // original initializations from the map. - auto combinedInit{ - inits.emplace(&combinedSymbol, static_cast(bytes))}; - evaluate::InitialImage &combined{combinedInit.first->second.image}; - combined.Incorporate(symbol.offset() - minStart, iter->second.image); - inits.erase(iter); - for (const Symbol *s : conflicts) { - auto sIter{inits.find(s)}; - CHECK(sIter != inits.end()); - combined.Incorporate(s->offset() - minStart, sIter->second.image); - inits.erase(sIter); - } - return true; // got one + // Add an EQUIVALENCE set to the scope so that the new object appears in + // the results of GetStorageAssociations(). + auto &newSet{scope.equivalenceSets().emplace_back()}; + newSet.emplace_back(combinedSymbol); + newSet.emplace_back(const_cast(first)); + } + return true; +} + +// When a statically-allocated derived type variable has no explicit +// initialization, but its type has at least one nonallocatable ultimate +// component with default initialization, make its initialization explicit. +[[maybe_unused]] static void MakeDefaultInitializationExplicit( + const Scope &scope, const std::list> &associations, + evaluate::FoldingContext &foldingContext, DataInitializations &inits) { + UnorderedSymbolSet equivalenced; + for (const std::list &association : associations) { + for (const Symbol &symbol : association) { + equivalenced.emplace(symbol); + } + } + for (const auto &pair : scope) { + const Symbol &symbol{*pair.second}; + if (!symbol.test(Symbol::Flag::InDataStmt) && + !HasDeclarationInitializer(symbol) && IsSaved(symbol) && + equivalenced.find(symbol) == equivalenced.end()) { + // Static object, no local storage association, no explicit initialization + if (const DerivedTypeSpec * derived{HasDefaultInitialization(symbol)}) { + auto newInitIter{inits.emplace(&symbol, symbol.size())}; + CHECK(newInitIter.second); + auto &newInit{newInitIter.first->second}; + PopulateWithComponentDefaults( + newInit, 0, *derived, foldingContext, symbol); + } + } } - return false; // no remaining EQUIVALENCE'd DATA initializations } -// Converts the initialization image for all the DATA statement appearances of -// a single symbol into an init() expression in the symbol table entry. +// Traverses the Scopes to: +// 1) combine initialization of equivalenced objects, & +// 2) optionally make initialization explicit for otherwise uninitialized static +// objects of derived types with default component initialization +// Returns false on error. +static bool ProcessScopes(const Scope &scope, + evaluate::ExpressionAnalyzer &exprAnalyzer, DataInitializations &inits) { + bool result{true}; // no error + switch (scope.kind()) { + case Scope::Kind::Global: + case Scope::Kind::Module: + case Scope::Kind::MainProgram: + case Scope::Kind::Subprogram: + case Scope::Kind::BlockData: + case Scope::Kind::Block: { + std::list> associations{GetStorageAssociations(scope)}; + for (const std::list &associated : associations) { + if (std::find_if(associated.begin(), associated.end(), [](SymbolRef ref) { + return IsInitialized(*ref); + }) != associated.end()) { + result &= + CombineEquivalencedInitialization(associated, exprAnalyzer, inits); + } + } + if constexpr (makeDefaultInitializationExplicit) { + MakeDefaultInitializationExplicit( + scope, associations, exprAnalyzer.GetFoldingContext(), inits); + } + for (const Scope &child : scope.children()) { + result &= ProcessScopes(child, exprAnalyzer, inits); + } + } break; + default:; + } + return result; +} + +// Converts the static initialization image for a single symbol with +// one or more DATA statement appearances. void ConstructInitializer(const Symbol &symbol, SymbolDataInitialization &initialization, evaluate::ExpressionAnalyzer &exprAnalyzer) { + std::list symbols{symbol}; + CheckForOverlappingInitialization( + symbols, initialization, exprAnalyzer, "DATA statement initializations"s); auto &context{exprAnalyzer.GetFoldingContext()}; - initialization.inits.sort(); - ConstantSubscript next{0}; - for (const auto &init : initialization.inits) { - if (init.start() < next) { - auto badDesignator{evaluate::OffsetToDesignator( - context, symbol, init.start(), init.size())}; - CHECK(badDesignator); - exprAnalyzer.Say(symbol.name(), - "DATA statement initializations affect '%s' more than once"_err_en_US, - badDesignator->AsFortran()); - } - next = init.start() + init.size(); - CHECK(next <= static_cast(initialization.image.size())); - } if (const auto *proc{symbol.detailsIf()}) { CHECK(IsProcedurePointer(symbol)); - const auto &procDesignator{initialization.image.AsConstantProcPointer()}; - CHECK(!procDesignator.GetComponent()); auto &mutableProc{const_cast(*proc)}; - mutableProc.set_init(DEREF(procDesignator.GetSymbol())); + if (MaybeExpr expr{initialization.image.AsConstantPointer()}) { + if (const auto *procDesignator{ + std::get_if(&expr->u)}) { + CHECK(!procDesignator->GetComponent()); + mutableProc.set_init(DEREF(procDesignator->GetSymbol())); + } else { + CHECK(evaluate::IsNullPointer(*expr)); + mutableProc.set_init(nullptr); + } + } else { + mutableProc.set_init(nullptr); + } } else if (const auto *object{symbol.detailsIf()}) { - if (auto symbolType{evaluate::DynamicType::From(symbol)}) { - auto &mutableObject{const_cast(*object)}; - if (IsPointer(symbol)) { + auto &mutableObject{const_cast(*object)}; + if (IsPointer(symbol)) { + if (auto ptr{initialization.image.AsConstantPointer()}) { + mutableObject.set_init(*ptr); + } else { + mutableObject.set_init(SomeExpr{evaluate::NullPointer{}}); + } + } else if (auto symbolType{evaluate::DynamicType::From(symbol)}) { + if (auto extents{evaluate::GetConstantExtents(context, symbol)}) { mutableObject.set_init( - initialization.image.AsConstantDataPointer(*symbolType)); + initialization.image.AsConstant(context, *symbolType, *extents)); } else { - if (auto extents{evaluate::GetConstantExtents(context, symbol)}) { - mutableObject.set_init( - initialization.image.AsConstant(context, *symbolType, *extents)); - } else { - exprAnalyzer.Say(symbol.name(), - "internal: unknown shape for '%s' while constructing initializer from DATA"_err_en_US, - symbol.name()); - return; - } + exprAnalyzer.Say(symbol.name(), + "internal: unknown shape for '%s' while constructing initializer from DATA"_err_en_US, + symbol.name()); + return; } } else { exprAnalyzer.Say(symbol.name(), @@ -552,10 +840,11 @@ void ConvertToInitializers( DataInitializations &inits, evaluate::ExpressionAnalyzer &exprAnalyzer) { - while (CombineSomeEquivalencedInits(inits, exprAnalyzer)) { - } - for (auto &[symbolPtr, initialization] : inits) { - ConstructInitializer(*symbolPtr, initialization, exprAnalyzer); + if (ProcessScopes( + exprAnalyzer.context().globalScope(), exprAnalyzer, inits)) { + for (auto &[symbolPtr, initialization] : inits) { + ConstructInitializer(*symbolPtr, initialization, exprAnalyzer); + } } } } // namespace Fortran::semantics diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -184,11 +184,25 @@ std::string buf; // stuff after CONTAINS in derived type llvm::raw_string_ostream typeBindings{buf}; for (const Symbol &symbol : sorted) { - PutSymbol(typeBindings, symbol); + if (!symbol.test(Symbol::Flag::CompilerCreated)) { + PutSymbol(typeBindings, symbol); + } } for (const Symbol &symbol : uses) { PutUse(symbol); } + for (const auto &set : scope.equivalenceSets()) { + if (!set.empty() && + !set.front().symbol.test(Symbol::Flag::CompilerCreated)) { + char punctuation{'('}; + decls_ << "equivalence"; + for (const auto &object : set) { + decls_ << punctuation << object.AsFortran(); + punctuation = ','; + } + decls_ << ")\n"; + } + } if (auto str{typeBindings.str()}; !str.empty()) { CHECK(scope.IsDerivedType()); decls_ << "contains\n" << str; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3757,7 +3757,7 @@ bool DeclarationVisitor::HasCycle( const Symbol &procSymbol, const ProcInterface &interface) { - OrderedSymbolSet procsInCycle; + SourceOrderedSymbolSet procsInCycle; procsInCycle.insert(procSymbol); const ProcInterface *thisInterface{&interface}; bool haveInterface{true}; @@ -5390,7 +5390,7 @@ } // Sets InDataStmt flag on a variable (or misidentified function) in a DATA -// statement so that the predicate IsStaticallyInitialized() will be true +// statement so that the predicate IsInitialized() will be true // during semantic analysis before the symbol's initializer is constructed. bool ConstructVisitor::Pre(const parser::DataIDoObject &x) { std::visit( diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp --- a/flang/lib/Semantics/runtime-type-info.cpp +++ b/flang/lib/Semantics/runtime-type-info.cpp @@ -264,11 +264,11 @@ object.set_shape(arraySpec); object.set_init(evaluate::AsGenericExpr(evaluate::Constant{ std::move(x), evaluate::ConstantSubscripts{elements}})); - const Symbol &symbol{ - *scope - .try_emplace( - name, Attrs{Attr::TARGET, Attr::SAVE}, std::move(object)) - .first->second}; + Symbol &symbol{*scope + .try_emplace(name, Attrs{Attr::TARGET, Attr::SAVE}, + std::move(object)) + .first->second}; + symbol.set(Symbol::Flag::CompilerCreated); return evaluate::AsGenericExpr( evaluate::Expr{evaluate::Designator{symbol}}); } @@ -301,11 +301,11 @@ object.set_init( evaluate::AsGenericExpr(evaluate::Constant{ derivedType, std::move(x), std::move(shape)})); - const Symbol &symbol{ - *scope - .try_emplace( - name, Attrs{Attr::TARGET, Attr::SAVE}, std::move(object)) - .first->second}; + Symbol &symbol{*scope + .try_emplace(name, Attrs{Attr::TARGET, Attr::SAVE}, + std::move(object)) + .first->second}; + symbol.set(Symbol::Flag::CompilerCreated); return evaluate::AsGenericExpr( evaluate::Designator{symbol}); } @@ -313,11 +313,12 @@ static SomeExpr SaveObjectInit( Scope &scope, SourceName name, const ObjectEntityDetails &object) { - const Symbol &symbol{*scope - .try_emplace(name, Attrs{Attr::TARGET, Attr::SAVE}, - ObjectEntityDetails{object}) - .first->second}; + Symbol &symbol{*scope + .try_emplace(name, Attrs{Attr::TARGET, Attr::SAVE}, + ObjectEntityDetails{object}) + .first->second}; CHECK(symbol.get().init().has_value()); + symbol.set(Symbol::Flag::CompilerCreated); return evaluate::AsGenericExpr( evaluate::Designator{symbol}); } @@ -615,6 +616,7 @@ Attrs{Attr::TARGET, Attr::SAVE}, std::move(object))}; CHECK(pair.second); Symbol &result{*pair.first->second}; + result.set(Symbol::Flag::CompilerCreated); return result; } @@ -638,11 +640,11 @@ using Ascii = evaluate::Type; using AsciiExpr = evaluate::Expr; object.set_init(evaluate::AsGenericExpr(AsciiExpr{name})); - const Symbol &symbol{ - *scope - .try_emplace(SaveObjectName(".n."s + name), - Attrs{Attr::TARGET, Attr::SAVE}, std::move(object)) - .first->second}; + Symbol &symbol{*scope + .try_emplace(SaveObjectName(".n."s + name), + Attrs{Attr::TARGET, Attr::SAVE}, std::move(object)) + .first->second}; + symbol.set(Symbol::Flag::CompilerCreated); return evaluate::AsGenericExpr( AsciiExpr{evaluate::Designator{symbol}}); } @@ -819,6 +821,7 @@ ".dp."s + distinctName + "."s + symbol.name().ToString())}; Symbol &ptrDtSym{ *scope.try_emplace(ptrDtName, Attrs{}, UnknownDetails{}).first->second}; + ptrDtSym.set(Symbol::Flag::CompilerCreated); Scope &ptrDtScope{scope.MakeScope(Scope::Kind::DerivedType, &ptrDtSym)}; ignoreScopes_.insert(&ptrDtScope); ObjectEntityDetails ptrDtObj; diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp --- a/flang/lib/Semantics/symbol.cpp +++ b/flang/lib/Semantics/symbol.cpp @@ -676,4 +676,38 @@ return y && *y == x; } +bool SymbolOffsetCompare::operator()( + const SymbolRef &x, const SymbolRef &y) const { + const Symbol *xCommon{FindCommonBlockContaining(*x)}; + const Symbol *yCommon{FindCommonBlockContaining(*y)}; + if (xCommon) { + if (yCommon) { + const SymbolSourcePositionCompare sourceCmp; + if (sourceCmp(*xCommon, *yCommon)) { + return true; + } else if (sourceCmp(*yCommon, *xCommon)) { + return false; + } else if (x->offset() == y->offset()) { + return x->size() > y->size(); + } else { + return x->offset() < y->offset(); + } + } else { + return false; + } + } else if (yCommon) { + return true; + } else if (x->offset() == y->offset()) { + return x->size() > y->size(); + } else { + return x->offset() < y->offset(); + } + return x->GetSemanticsContext().allCookedSources().Precedes( + x->name(), y->name()); +} +bool SymbolOffsetCompare::operator()( + const MutableSymbolRef &x, const MutableSymbolRef &y) const { + return (*this)(SymbolRef{*x}, SymbolRef{*y}); +} + } // namespace Fortran::semantics diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -507,6 +507,18 @@ return nullptr; } +const EquivalenceSet *FindEquivalenceSet(const Symbol &symbol) { + const Symbol &ultimate{symbol.GetUltimate()}; + for (const EquivalenceSet &set : ultimate.owner().equivalenceSets()) { + for (const EquivalenceObject &object : set) { + if (object.symbol == ultimate) { + return &set; + } + } + } + return nullptr; +} + bool IsExtensibleType(const DerivedTypeSpec *derived) { return derived && !IsIsoCType(derived) && !derived->typeSymbol().attrs().test(Attr::BIND_C) && @@ -569,34 +581,36 @@ } } -bool IsStaticallyInitialized(const Symbol &symbol, bool ignoreDATAstatements) { - if (!ignoreDATAstatements && symbol.test(Symbol::Flag::InDataStmt)) { - return true; - } else if (IsNamedConstant(symbol)) { +bool HasDeclarationInitializer(const Symbol &symbol) { + if (IsNamedConstant(symbol)) { return false; } else if (const auto *object{symbol.detailsIf()}) { return object->init().has_value(); } else if (const auto *proc{symbol.detailsIf()}) { return proc->init().has_value(); + } else { + return false; } - return false; } -bool IsInitialized(const Symbol &symbol, bool ignoreDATAstatements, - const Symbol *derivedTypeSymbol) { - if (IsStaticallyInitialized(symbol, ignoreDATAstatements) || - IsAllocatable(symbol)) { +bool IsInitialized(const Symbol &symbol, bool ignoreDataStatements) { + if (IsAllocatable(symbol) || + (!ignoreDataStatements && symbol.test(Symbol::Flag::InDataStmt)) || + HasDeclarationInitializer(symbol)) { return true; } else if (IsNamedConstant(symbol) || IsFunctionResult(symbol) || IsPointer(symbol)) { return false; } else if (const auto *object{symbol.detailsIf()}) { if (!object->isDummy() && object->type()) { - const auto *derived{object->type()->AsDerived()}; - // error recovery: avoid infinite recursion on invalid - // recursive usage of a derived type - return derived && &derived->typeSymbol() != derivedTypeSymbol && - derived->HasDefaultInitialization(); + if (const auto *derived{object->type()->AsDerived()}) { + DirectComponentIterator directs{*derived}; + return bool{std::find_if( + directs.begin(), directs.end(), [](const Symbol &component) { + return IsAllocatable(component) || + HasDeclarationInitializer(component); + })}; + } } } return false; @@ -788,6 +802,39 @@ return ClassifyProcedure(symbol) == ProcedureDefinitionClass::External; } +// Most scopes have no EQUIVALENCE, and this function is a fast no-op for them. +std::list> GetStorageAssociations(const Scope &scope) { + UnorderedSymbolSet distinct; + for (const EquivalenceSet &set : scope.equivalenceSets()) { + for (const EquivalenceObject &object : set) { + distinct.emplace(object.symbol); + } + } + // This set is ordered by ascending offsets, with ties broken by greatest + // size. A multiset is used here because multiple symbols may have the + // same offset and size; the symbols in the set, however, are distinct. + std::multiset associated; + for (SymbolRef ref : distinct) { + associated.emplace(*ref); + } + std::list> result; + std::size_t limit{0}; + const Symbol *currentCommon{nullptr}; + for (const Symbol &symbol : associated) { + const Symbol *thisCommon{FindCommonBlockContaining(symbol)}; + if (result.empty() || symbol.offset() >= limit || + thisCommon != currentCommon) { + // Start a new group + result.emplace_back(std::list{}); + limit = 0; + currentCommon = thisCommon; + } + result.back().emplace_back(symbol); + limit = std::max(limit, symbol.offset() + symbol.size()); + } + return result; +} + bool IsModuleProcedure(const Symbol &symbol) { return ClassifyProcedure(symbol) == ProcedureDefinitionClass::Module; } diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp --- a/flang/lib/Semantics/type.cpp +++ b/flang/lib/Semantics/type.cpp @@ -179,10 +179,8 @@ bool DerivedTypeSpec::HasDefaultInitialization() const { DirectComponentIterator components{*this}; - return bool{std::find_if( - components.begin(), components.end(), [&](const Symbol &component) { - return IsInitialized(component, false, &typeSymbol()); - })}; + return bool{std::find_if(components.begin(), components.end(), + [&](const Symbol &component) { return IsInitialized(component); })}; } bool DerivedTypeSpec::HasDestruction() const { diff --git a/flang/test/Semantics/data12.f90 b/flang/test/Semantics/data12.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/data12.f90 @@ -0,0 +1,35 @@ +! RUN: %S/test_errors.sh %s %t %flang_fc1 +! REQUIRES: shell +type :: t1 + sequence + integer :: m = 123 + integer :: pad +end type +type :: t2 + sequence + integer :: n = 123 + integer :: pad +end type +type :: t3 + sequence + integer :: k = 234 + integer :: pad +end type +!ERROR: Distinct default component initializations of equivalenced objects affect 'x1a%m' more than once +type(t1) :: x1a +!ERROR: Distinct default component initializations of equivalenced objects affect 'x2a%n' more than once +type(t2) :: x2a +!ERROR: Distinct default component initializations of equivalenced objects affect 'x3%k' more than once +type(t3), save :: x3 +!ERROR: Explicit initializations of equivalenced objects affect 'ja(2_8)' more than once +!ERROR: Explicit initializations of equivalenced objects affect 'ka(1_8)' more than once +integer :: ja(2), ka(2) +data ja/345, 456/ +data ka/456, 567/ +equivalence(x1a, x2a, x3) +! Same value: no error +type(t1) :: x1b +type(t2) :: x2b +equivalence(x1b, x2b) +equivalence(ja(2),ka(1)) +end diff --git a/flang/test/Semantics/data13.f90 b/flang/test/Semantics/data13.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/data13.f90 @@ -0,0 +1,32 @@ +! RUN: %flang_fc1 -fsyntax-only -fdebug-dump-symbols %s 2>&1 | FileCheck %s +! Verify that the closure of EQUIVALENCE'd symbols with any DATA +! initialization produces a combined initializer, with explicit +! initialization overriding any default component initialization. +! CHECK: .F18.0, SAVE (CompilerCreated) size=8 offset=0: ObjectEntity type: INTEGER(4) shape: 1_8:2_8 init:[INTEGER(4)::456_4,234_4] +! CHECK: ja (InDataStmt) size=8 offset=0: ObjectEntity type: INTEGER(4) shape: 1_8:2_8 +! CHECK-NOT: x0, SAVE size=8 offset=8: ObjectEntity type: TYPE(t1) init:t1(m=123_4,n=234_4) +! CHECK: x1 size=8 offset=16: ObjectEntity type: TYPE(t1) init:t1(m=345_4,n=234_4) +! CHECK: x2 size=8 offset=0: ObjectEntity type: TYPE(t1) +! CHECK-NOT: x3a, SAVE size=8 offset=24: ObjectEntity type: TYPE(t3) init:t3(t2=t2(k=567_4),j=0_4) +! CHECK: x3b size=8 offset=32: ObjectEntity type: TYPE(t3) init:t3(k=567_4,j=678_4) +! CHECK: Equivalence Sets: (x2,ja(1)) (.F18.0,x2) +type :: t1 + sequence + integer :: m = 123 + integer :: n = 234 +end type +type :: t2 + integer :: k = 567 +end type +type, extends(t2) :: t3 + integer :: j ! uninitialized +end type +type(t1), save :: x0 ! not enabled +type(t1) :: x1 = t1(m=345) +type(t1) :: x2 +type(t3), save :: x3a ! not enabled +type(t3) :: x3b = t3(j=678) +integer :: ja(2) +equivalence(x2, ja) +data ja(1)/456/ +end diff --git a/flang/test/Semantics/typeinfo01.f90 b/flang/test/Semantics/typeinfo01.f90 --- a/flang/test/Semantics/typeinfo01.f90 +++ b/flang/test/Semantics/typeinfo01.f90 @@ -6,10 +6,10 @@ integer :: n end type !CHECK: Module scope: m01 -!CHECK: .c.t1, SAVE, TARGET: ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.n,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.t1, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .n.n, SAVE, TARGET: ObjectEntity type: CHARACTER(1_8,1) init:"n" -!CHECK: .n.t1, SAVE, TARGET: ObjectEntity type: CHARACTER(2_8,1) init:"t1" +!CHECK: .c.t1, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.n,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] +!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .n.n, SAVE, TARGET (CompilerCreated): ObjectEntity type: CHARACTER(1_8,1) init:"n" +!CHECK: .n.t1, SAVE, TARGET (CompilerCreated): ObjectEntity type: CHARACTER(2_8,1) init:"t1" !CHECK: DerivedType scope: t1 end module @@ -20,10 +20,10 @@ type, extends(parent) :: child integer :: cn end type -!CHECK: .c.child, SAVE, TARGET: ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.parent,genre=1_1,category=5_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.parent,lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.cn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=4_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .c.parent, SAVE, TARGET: ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.pn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.child, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.child,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.child,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .dt.parent, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.parent,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.parent,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .c.child, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.parent,genre=1_1,category=5_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.parent,lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.cn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=4_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] +!CHECK: .c.parent, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.pn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] +!CHECK: .dt.child, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.child,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.child,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.parent, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.parent,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.parent,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) end module module m03 @@ -32,11 +32,11 @@ real(kind=k) :: a end type type(kpdt(4)) :: x -!CHECK: .c.kpdt.0, SAVE, TARGET: ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.a,genre=1_1,category=1_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.kpdt, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.kpdt,uninstantiated=NULL(),kindparameter=.kp.kpdt,lenparameterkind=NULL()) -!CHECK: .dt.kpdt.0, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.kpdt,sizeinbytes=4_8,uninstantiated=.dt.kpdt,kindparameter=.kp.kpdt.0,lenparameterkind=NULL(),component=.c.kpdt.0,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .kp.kpdt, SAVE, TARGET: ObjectEntity type: INTEGER(8) shape: 0_8:0_8 init:[INTEGER(8)::1_8] -!CHECK: .kp.kpdt.0, SAVE, TARGET: ObjectEntity type: INTEGER(8) shape: 0_8:0_8 init:[INTEGER(8)::4_8] +!CHECK: .c.kpdt.0, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.a,genre=1_1,category=1_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] +!CHECK: .dt.kpdt, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.kpdt,uninstantiated=NULL(),kindparameter=.kp.kpdt,lenparameterkind=NULL()) +!CHECK: .dt.kpdt.0, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.kpdt,sizeinbytes=4_8,uninstantiated=.dt.kpdt,kindparameter=.kp.kpdt.0,lenparameterkind=NULL(),component=.c.kpdt.0,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .kp.kpdt, SAVE, TARGET (CompilerCreated): ObjectEntity type: INTEGER(8) shape: 0_8:0_8 init:[INTEGER(8)::1_8] +!CHECK: .kp.kpdt.0, SAVE, TARGET (CompilerCreated): ObjectEntity type: INTEGER(8) shape: 0_8:0_8 init:[INTEGER(8)::4_8] end module module m04 @@ -49,8 +49,8 @@ subroutine s1(x) class(tbps), intent(in) :: x end subroutine -!CHECK: .dt.tbps, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.tbps,name=.n.tbps,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .v.tbps, SAVE, TARGET: ObjectEntity type: TYPE(binding) shape: 0_8:1_8 init:[binding::binding(proc=s1,name=.n.b1),binding(proc=s1,name=.n.b2)] +!CHECK: .dt.tbps, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.tbps,name=.n.tbps,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .v.tbps, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(binding) shape: 0_8:1_8 init:[binding::binding(proc=s1,name=.n.b1),binding(proc=s1,name=.n.b2)] end module module m05 @@ -61,8 +61,8 @@ subroutine s1(x) class(t), intent(in) :: x end subroutine -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=24_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=.p.t,special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .p.t, SAVE, TARGET: ObjectEntity type: TYPE(procptrcomponent) shape: 0_8:0_8 init:[procptrcomponent::procptrcomponent(name=.n.p1,offset=0_8,initialization=s1)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=24_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=.p.t,special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .p.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(procptrcomponent) shape: 0_8:0_8 init:[procptrcomponent::procptrcomponent(name=.n.p1,offset=0_8,initialization=s1)] end module module m06 @@ -84,12 +84,12 @@ class(t2), intent(out) :: x class(t), intent(in) :: y end subroutine -!CHECK: .c.t2, SAVE, TARGET: ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=5_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .dt.t2, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .s.t, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,proc=s1)] -!CHECK: .v.t, SAVE, TARGET: ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] -!CHECK: .v.t2, SAVE, TARGET: ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s2,name=.n.s1)] +!CHECK: .c.t2, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=5_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,proc=s1)] +!CHECK: .v.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] +!CHECK: .v.t2, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s2,name=.n.s1)] end module module m07 @@ -103,9 +103,9 @@ class(t), intent(out) :: x class(t), intent(in) :: y end subroutine -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=4_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .s.t, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=3_1,proc=s1)] -!CHECK: .v.t, SAVE, TARGET: ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=4_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=3_1,proc=s1)] +!CHECK: .v.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] end module module m08 @@ -123,8 +123,8 @@ impure elemental subroutine s3(x) type(t) :: x end subroutine -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=3200_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) -!CHECK: .s.t, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:2_8 init:[specialbinding::specialbinding(which=7_1,isargdescriptorset=0_1,proc=s3),specialbinding(which=10_1,isargdescriptorset=1_1,proc=s1),specialbinding(which=11_1,isargdescriptorset=0_1,proc=s2)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=3200_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(specialbinding) shape: 0_8:2_8 init:[specialbinding::specialbinding(which=7_1,isargdescriptorset=0_1,proc=s3),specialbinding(which=10_1,isargdescriptorset=1_1,proc=s1),specialbinding(which=11_1,isargdescriptorset=0_1,proc=s2)] end module module m09 @@ -165,9 +165,9 @@ integer, intent(out) :: iostat character(len=*), intent(inout) :: iomsg end subroutine -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .s.t, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=1_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=1_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=1_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=1_1,proc=wu)] -!CHECK: .v.t, SAVE, TARGET: ObjectEntity type: TYPE(binding) shape: 0_8:3_8 init:[binding::binding(proc=rf,name=.n.rf),binding(proc=ru,name=.n.ru),binding(proc=wf,name=.n.wf),binding(proc=wu,name=.n.wu)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=1_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=1_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=1_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=1_1,proc=wu)] +!CHECK: .v.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(binding) shape: 0_8:3_8 init:[binding::binding(proc=rf,name=.n.rf),binding(proc=ru,name=.n.ru),binding(proc=wf,name=.n.wf),binding(proc=wu,name=.n.wu)] end module module m10 @@ -214,8 +214,8 @@ integer, intent(out) :: iostat character(len=*), intent(inout) :: iomsg end subroutine -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .s.t, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=0_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=0_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=0_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=0_1,proc=wu)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=0_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=0_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=0_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=0_1,proc=wu)] end module module m11 @@ -227,16 +227,16 @@ character(len=len) :: chauto real :: automatic(len) end type -!CHECK: .dt.t, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.t) -!CHECK: .lpk.t, SAVE, TARGET: ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::8_1] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.t) +!CHECK: .lpk.t, SAVE, TARGET (CompilerCreated): ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::8_1] contains subroutine s1(x) -!CHECK: .b.t.1.automatic, SAVE, TARGET: ObjectEntity type: TYPE(value) shape: 0_8:1_8,0_8:0_8 init:reshape([value::value(genre=2_1,value=1_8),value(genre=3_1,value=0_8)],shape=[2,1]) -!CHECK: .c.t.1, SAVE, TARGET: ObjectEntity type: TYPE(component) shape: 0_8:3_8 init:[component::component(name=.n.allocatable,genre=3_1,category=1_1,kind=4_1,rank=1_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.pointer,genre=2_1,category=1_1,kind=4_1,rank=0_1,offset=48_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=.di.t.1.pointer),component(name=.n.chauto,genre=4_1,category=3_1,kind=1_1,rank=0_1,offset=72_8,characterlen=value(genre=3_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.automatic,genre=4_1,category=1_1,kind=4_1,rank=1_1,offset=96_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=.b.t.1.automatic,initialization=NULL())] -!CHECK: .di.t.1.pointer, SAVE, TARGET: ObjectEntity type: TYPE(.dp.t.1.pointer) init:.dp.t.1.pointer(pointer=target) -!CHECK: .dp.t.1.pointer: DerivedType components: pointer -!CHECK: .dt.t.1, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=144_8,uninstantiated=.dt.t,kindparameter=NULL(),lenparameterkind=.lpk.t.1,component=.c.t.1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) -!CHECK: .lpk.t.1, SAVE, TARGET: ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::8_1] +!CHECK: .b.t.1.automatic, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(value) shape: 0_8:1_8,0_8:0_8 init:reshape([value::value(genre=2_1,value=1_8),value(genre=3_1,value=0_8)],shape=[2,1]) +!CHECK: .c.t.1, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(component) shape: 0_8:3_8 init:[component::component(name=.n.allocatable,genre=3_1,category=1_1,kind=4_1,rank=1_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.pointer,genre=2_1,category=1_1,kind=4_1,rank=0_1,offset=48_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=.di.t.1.pointer),component(name=.n.chauto,genre=4_1,category=3_1,kind=1_1,rank=0_1,offset=72_8,characterlen=value(genre=3_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.automatic,genre=4_1,category=1_1,kind=4_1,rank=1_1,offset=96_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=.b.t.1.automatic,initialization=NULL())] +!CHECK: .di.t.1.pointer, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(.dp.t.1.pointer) init:.dp.t.1.pointer(pointer=target) +!CHECK: .dp.t.1.pointer (CompilerCreated): DerivedType components: pointer +!CHECK: .dt.t.1, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=144_8,uninstantiated=.dt.t,kindparameter=NULL(),lenparameterkind=.lpk.t.1,component=.c.t.1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) +!CHECK: .lpk.t.1, SAVE, TARGET (CompilerCreated): ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::8_1] !CHECK: DerivedType scope: .dp.t.1.pointer size=24 alignment=8 instantiation of .dp.t.1.pointer !CHECK: pointer, POINTER size=24 offset=0: ObjectEntity type: REAL(4) type(t(*)), intent(in) :: x @@ -248,9 +248,9 @@ integer :: n integer :: n2 integer :: n_3 - ! CHECK: .n.n, SAVE, TARGET: ObjectEntity type: CHARACTER(1_8,1) init:"n" - ! CHECK: .n.n2, SAVE, TARGET: ObjectEntity type: CHARACTER(2_8,1) init:"n2" - ! CHECK: .n.n_3, SAVE, TARGET: ObjectEntity type: CHARACTER(3_8,1) init:"n_3" + ! CHECK: .n.n, SAVE, TARGET (CompilerCreated): ObjectEntity type: CHARACTER(1_8,1) init:"n" + ! CHECK: .n.n2, SAVE, TARGET (CompilerCreated): ObjectEntity type: CHARACTER(2_8,1) init:"n2" + ! CHECK: .n.n_3, SAVE, TARGET (CompilerCreated): ObjectEntity type: CHARACTER(3_8,1) init:"n_3" end type end module @@ -260,7 +260,7 @@ contains procedure :: assign1, assign2 generic :: assignment(=) => assign1, assign2 - ! CHECK: .s.t1, SAVE, TARGET: ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=3_1,proc=assign1)] + ! CHECK: .s.t1, SAVE, TARGET (CompilerCreated): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=3_1,proc=assign1)] end type contains impure elemental subroutine assign1(to, from)