diff --git a/flang/include/flang/Parser/char-block.h b/flang/include/flang/Parser/char-block.h --- a/flang/include/flang/Parser/char-block.h +++ b/flang/include/flang/Parser/char-block.h @@ -138,6 +138,13 @@ return right < left; } +// An alternative comparator based on pointer values; use with care! +struct CharBlockPointerComparator { + bool operator()(CharBlock x, CharBlock y) const { + return x.end() < y.begin(); + } +}; + llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const CharBlock &x); } // namespace Fortran::parser diff --git a/flang/include/flang/Parser/provenance.h b/flang/include/flang/Parser/provenance.h --- a/flang/include/flang/Parser/provenance.h +++ b/flang/include/flang/Parser/provenance.h @@ -47,6 +47,7 @@ // necessary.) class AllSources; +class AllCookedSources; class Provenance { public: @@ -219,6 +220,9 @@ // single instances of CookedSource. class CookedSource { public: + int number() const { return number_; } + void set_number(int n) { number_ = n; } + CharBlock AsCharBlock() const { return CharBlock{data_}; } std::optional GetProvenanceRange(CharBlock) const; std::optional GetCharBlock(ProvenanceRange) const; @@ -242,11 +246,12 @@ } std::size_t BufferedBytes() const; - void Marshal(AllSources &); // marshals text into one contiguous block + void Marshal(AllCookedSources &); // marshals text into one contiguous block void CompileProvenanceRangeToOffsetMappings(AllSources &); llvm::raw_ostream &Dump(llvm::raw_ostream &) const; private: + int number_{0}; // for sorting purposes CharBuffer buffer_; // before Marshal() std::string data_; // all of it, prescanned and preprocessed OffsetToProvenanceMappings provenanceMap_; @@ -263,15 +268,8 @@ CookedSource &NewCookedSource(); - template // const char * or CharBlock - const CookedSource *Find(A x) const { - for (const auto &c : cooked_) { - if (c.AsCharBlock().Contains(x)) { - return &c; - } - } - return nullptr; - } + const CookedSource *Find(CharBlock) const; + const CookedSource *Find(const char *p) const { return Find(CharBlock{p}); } bool IsValid(ProvenanceRange r) const { return allSources_.IsValid(r); } @@ -283,9 +281,30 @@ std::optional GetCharBlock(ProvenanceRange) const; void Dump(llvm::raw_ostream &) const; + // For sorting symbol names without being dependent on pointer values + bool Precedes(CharBlock, CharBlock) const; + + // Once a CookedSource is complete, add it to index_ and assign its number_ + void Register(CookedSource &); + private: AllSources &allSources_; std::list cooked_; // owns all CookedSource instances + int counter_{0}; + std::map index_; }; + +// For use as a Comparator for maps, sets, sorting, &c. +class CharBlockComparator { +public: + explicit CharBlockComparator(const AllCookedSources &all) : all_{all} {} + bool operator()(CharBlock x, CharBlock y) const { + return all_.Precedes(x, y); + } + +private: + const AllCookedSources &all_; +}; + } // namespace Fortran::parser #endif // FORTRAN_PARSER_PROVENANCE_H_ 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 @@ -62,9 +62,10 @@ using ImportKind = common::ImportKind; // Create the Global scope -- the root of the scope tree - Scope() : Scope{*this, Kind::Global, nullptr} {} - Scope(Scope &parent, Kind kind, Symbol *symbol) - : parent_{parent}, kind_{kind}, symbol_{symbol} { + explicit Scope(SemanticsContext &context) + : Scope{*this, Kind::Global, nullptr, context} {} + Scope(Scope &parent, Kind kind, Symbol *symbol, SemanticsContext &context) + : parent_{parent}, kind_{kind}, symbol_{symbol}, context_{context} { if (symbol) { symbol->set_scope(this); } @@ -99,6 +100,7 @@ } Symbol *symbol() { return symbol_; } const Symbol *symbol() const { return symbol_; } + SemanticsContext &context() const { return context_; } inline const Symbol *GetSymbol() const; const Scope *GetDerivedTypeParent() const; @@ -107,6 +109,9 @@ bool Contains(const Scope &) const; /// Make a scope nested in this one Scope &MakeScope(Kind kind, Symbol *symbol = nullptr); + SemanticsContext &GetMutableSemanticsContext() const { + return const_cast(context()); + } using size_type = mapType::size_type; using iterator = mapType::iterator; @@ -244,7 +249,7 @@ symbol_->test(Symbol::Flag::ModFile); } - void InstantiateDerivedTypes(SemanticsContext &); + void InstantiateDerivedTypes(); const Symbol *runtimeDerivedTypeDescription() const { return runtimeDerivedTypeDescription_; @@ -273,8 +278,9 @@ parser::Message::Reference instantiationContext_; bool hasSAVE_{false}; // scope has a bare SAVE statement const Symbol *runtimeDerivedTypeDescription_{nullptr}; + SemanticsContext &context_; // When additional data members are added to Scope, remember to - // copy them, if appropriate, in InstantiateDerivedType(). + // copy them, if appropriate, in FindOrInstantiateDerivedType(). // Storage for all Symbols. Every Symbol is in allSymbols and every Symbol* // or Symbol& points to one in there. 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 @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include namespace llvm { @@ -595,10 +595,13 @@ bool operator==(const Symbol &that) const { return this == &that; } bool operator!=(const Symbol &that) const { return !(*this == that); } - bool operator<(const Symbol &that) const { - // Used to collate symbols by creation order - return sortIndex_ < that.sortIndex_; - } + + // Symbol comparison is 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. + // (This function is implemented in Evaluate/tools.cpp to + // satisfy complicated shared library interdependency.) + bool operator<(const Symbol &) const; int Rank() const { return std::visit( @@ -651,10 +654,11 @@ // for a parameterized derived type instantiation with the instance's scope. const DerivedTypeSpec *GetParentTypeSpec(const Scope * = nullptr) const; + SemanticsContext &GetSemanticsContext() const; + private: const Scope *owner_; SourceName name_; - std::size_t sortIndex_; // to implement "operator<" platform independently Attrs attrs_; Flags flags_; Scope *scope_{nullptr}; @@ -689,7 +693,6 @@ Symbol &symbol = Get(); symbol.owner_ = &owner; symbol.name_ = name; - symbol.sortIndex_ = ++symbolCount_; symbol.attrs_ = attrs; symbol.details_ = std::move(details); return symbol; @@ -700,7 +703,6 @@ std::list blocks_; std::size_t nextIndex_{0}; blockType *currBlock_{nullptr}; - static inline std::size_t symbolCount_ = 0; Symbol &Get() { if (nextIndex_ == 0) { @@ -765,17 +767,13 @@ details_); } -inline bool operator<(SymbolRef x, SymbolRef y) { return *x < *y; } +inline bool operator<(SymbolRef x, SymbolRef y) { + return *x < *y; // name source position ordering +} inline bool operator<(MutableSymbolRef x, MutableSymbolRef y) { - return *x < *y; + return *x < *y; // name source position ordering } -struct SymbolHash { - std::size_t operator()(SymbolRef symRef) const { - std::hash hasher; - return hasher(symRef->name().ToString()); - } -}; -using SymbolSet = std::unordered_set; +using SymbolSet = std::set; } // namespace Fortran::semantics diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1203,4 +1203,16 @@ return FindFunctionResult(symbol, seen); } +// These are here in Evaluate/tools.cpp so that Evaluate can use +// them; they cannot be defined in symbol.h due to the dependence +// on Scope. + +bool Symbol::operator<(const Symbol &that) const { + return GetSemanticsContext().allCookedSources().Precedes(name_, that.name_); +} + +SemanticsContext &Symbol::GetSemanticsContext() const { + return DEREF(owner_).context(); +} + } // namespace Fortran::semantics diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp --- a/flang/lib/Parser/parsing.cpp +++ b/flang/lib/Parser/parsing.cpp @@ -88,7 +88,7 @@ // message about nonstandard usage will have provenance. currentCooked_->Put('\n', range.start()); } - currentCooked_->Marshal(allSources); + currentCooked_->Marshal(allCooked_); if (options.needProvenanceRangeToCharBlockMappings) { currentCooked_->CompileProvenanceRangeToOffsetMappings(allSources); } diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp --- a/flang/lib/Parser/provenance.cpp +++ b/flang/lib/Parser/provenance.cpp @@ -442,11 +442,13 @@ std::size_t CookedSource::BufferedBytes() const { return buffer_.bytes(); } -void CookedSource::Marshal(AllSources &allSources) { +void CookedSource::Marshal(AllCookedSources &allCookedSources) { CHECK(provenanceMap_.SizeInBytes() == buffer_.bytes()); - provenanceMap_.Put(allSources.AddCompilerInsertion("(after end of source)")); + provenanceMap_.Put(allCookedSources.allSources().AddCompilerInsertion( + "(after end of source)")); data_ = buffer_.Marshal(); buffer_.clear(); + allCookedSources.Register(*this); } void CookedSource::CompileProvenanceRangeToOffsetMappings( @@ -534,6 +536,16 @@ return cooked_.emplace_back(); } +const CookedSource *AllCookedSources::Find(CharBlock x) const { + auto pair{index_.equal_range(x)}; + for (auto iter{pair.first}; iter != pair.second; ++iter) { + if (iter->second.AsCharBlock().Contains(x)) { + return &iter->second; + } + } + return nullptr; +} + std::optional AllCookedSources::GetProvenanceRange( CharBlock cb) const { if (const CookedSource * c{Find(cb)}) { @@ -589,4 +601,27 @@ } } +bool AllCookedSources::Precedes(CharBlock x, CharBlock y) const { + const CookedSource *ySource{Find(y)}; + if (const CookedSource * xSource{Find(x)}) { + if (ySource) { + int xNum{xSource->number()}; + int yNum{ySource->number()}; + return xNum < yNum || (xNum == yNum && x.begin() < y.begin()); + } else { + return true; // by fiat, all cooked source < anything outside + } + } else if (ySource) { + return false; + } else { + // Both names are compiler-created (SaveTempName). + return x < y; + } +} + +void AllCookedSources::Register(CookedSource &cooked) { + index_.emplace(cooked.AsCharBlock(), cooked); + cooked.set_number(static_cast(index_.size())); +} + } // namespace Fortran::parser diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp --- a/flang/lib/Semantics/check-io.cpp +++ b/flang/lib/Semantics/check-io.cpp @@ -930,7 +930,8 @@ if (const auto *var{parser::Unwrap(variable)}) { if (auto expr{AnalyzeExpr(context_, *var)}) { auto at{var->GetSource()}; - if (auto whyNot{WhyNotModifiable(at, *expr, context_.FindScope(at))}) { + if (auto whyNot{WhyNotModifiable(at, *expr, context_.FindScope(at), + true /*vectorSubscriptIsOk*/)}) { const Symbol *base{GetFirstSymbol(*expr)}; context_ .Say(at, "%s variable '%s' must be definable"_err_en_US, s, 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 @@ -6393,7 +6393,7 @@ CheckPossibleBadForwardRef(symbol); } } - currScope().InstantiateDerivedTypes(context()); + currScope().InstantiateDerivedTypes(); for (const auto &decl : decls) { if (const auto *statement{std::get_if< parser::Statement>>( diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -50,7 +50,7 @@ } Scope &Scope::MakeScope(Kind kind, Symbol *symbol) { - return children_.emplace_back(*this, kind, symbol); + return children_.emplace_back(*this, kind, symbol, context_); } template @@ -404,11 +404,11 @@ return *child; } -void Scope::InstantiateDerivedTypes(SemanticsContext &context) { +void Scope::InstantiateDerivedTypes() { for (DeclTypeSpec &type : declTypeSpecs_) { if (type.category() == DeclTypeSpec::TypeDerived || type.category() == DeclTypeSpec::ClassDerived) { - type.derivedTypeSpec().Instantiate(*this, context); + type.derivedTypeSpec().Instantiate(*this, context_); } } } diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp --- a/flang/lib/Semantics/semantics.cpp +++ b/flang/lib/Semantics/semantics.cpp @@ -185,8 +185,9 @@ : defaultKinds_{defaultKinds}, languageFeatures_{languageFeatures}, allCookedSources_{allCookedSources}, intrinsics_{evaluate::IntrinsicProcTable::Configure(defaultKinds_)}, - foldingContext_{ - parser::ContextualMessages{&messages_}, defaultKinds_, intrinsics_} {} + globalScope_{*this}, foldingContext_{ + parser::ContextualMessages{&messages_}, + defaultKinds_, intrinsics_} {} SemanticsContext::~SemanticsContext() {} diff --git a/flang/test/Semantics/data05.f90 b/flang/test/Semantics/data05.f90 --- a/flang/test/Semantics/data05.f90 +++ b/flang/test/Semantics/data05.f90 @@ -73,15 +73,15 @@ end function subroutine s11 real, target, save :: arr(3,4) ! CHECK: arr, SAVE, TARGET size=48 offset=0: ObjectEntity type: REAL(4) shape: 1_8:3_8,1_8:4_8 - type(t1) :: d1 = t1(1,reshape([1,2,3,4],[2,2]),(6.,7.),.false.,'ab',arr,ifunc2,rfunc,extrfunc) ! CHECK: d1 size=192 offset=48: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(c=[CHARACTER(KIND=1,LEN=1)::"a","a"],ifptr=ifunc2,j=1_4,rp=rfunc,t=.false._4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),xp=arr,xrp=extrfunc,z=(6._4,7._4)) + type(t1) :: d1 = t1(1,reshape([1,2,3,4],[2,2]),(6.,7.),.false.,'ab',arr,ifunc2,rfunc,extrfunc) ! CHECK: d1 size=184 offset=48: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) type(t1(4,len=1)) :: d2 = t1(4)(xrp=extrfunc,rp=rfunc,ifptr=ifunc2,xp=arr,c='a& - &b',t=.false.,z=(6.,7.),x=reshape([1,2,3,4],[2,2]),j=1) ! CHECK: d2 size=192 offset=240: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(c=[CHARACTER(KIND=1,LEN=1)::"a","a"],ifptr=ifunc2,j=1_4,rp=rfunc,t=.false._4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),xp=arr,xrp=extrfunc,z=(6._4,7._4)) - type(t1(2+2)) :: d3 ! CHECK: d3 (InDataStmt) size=192 offset=432: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(c=[CHARACTER(KIND=1,LEN=1)::"a","a"],ifptr=ifunc2,j=1_4,rp=rfunc,t=.false._4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),xp=arr,xrp=extrfunc,z=(6._4,7._4)) + &b',t=.false.,z=(6.,7.),x=reshape([1,2,3,4],[2,2]),j=1) ! CHECK: d2 size=184 offset=232: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) + type(t1(2+2)) :: d3 ! CHECK: d3 (InDataStmt) size=184 offset=416: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) data d3/t1(1,reshape([1,2,3,4],[2,2]),(6.,7.),.false.,'ab',arr,ifunc2,rfunc,extrfunc)/ - type(t1) :: d4 ! CHECK: d4 (InDataStmt) size=192 offset=624: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(c=[CHARACTER(KIND=1,LEN=1)::"a","a"],ifptr=ifunc2,j=1_4,rp=rfunc,t=.false._4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),xp=arr,xrp=extrfunc,z=(6._4,7._4)) + type(t1) :: d4 ! CHECK: d4 (InDataStmt) size=184 offset=600: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) data d4/t1(4)(xrp=extrfunc,rp=rfunc,ifptr=ifunc2,xp=arr,c='ab',t=.false.,z=(6& &.,7.),x=reshape([1,2,3,4],[2,2]),j=1)/ - type(t1) :: d5 ! CHECK: d5 (InDataStmt) size=192 offset=816: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(c=[CHARACTER(KIND=1,LEN=1)::"a","b"],ifptr=ifunc2,j=1_4,rp=rfunc,t=.false._4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),xp=arr,xrp=extrfunc,z=(6._4,7._4)) + type(t1) :: d5 ! CHECK: d5 (InDataStmt) size=184 offset=784: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","b"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) data d5%j/1/,d5%x/1,2,3,4/,d5%z%re/6./,d5%z%im/7./,d5%t/.false./,d5%c(1:1)/'a'/,d5%c(2:& &2)/'b'/,d5%xp/arr/,d5%ifptr/ifunc2/,d5%rp/rfunc/,d5%xrp/extrfunc/ end subroutine diff --git a/flang/test/Semantics/modfile21.f90 b/flang/test/Semantics/modfile21.f90 --- a/flang/test/Semantics/modfile21.f90 +++ b/flang/test/Semantics/modfile21.f90 @@ -26,10 +26,10 @@ ! real(4)::v ! complex(4)::w ! real(4)::cb -! common//t,w,u,v ! common/cb/x,y,z ! bind(c, name="CB")::/cb/ ! common/cb2/a,b,c ! bind(c)::/cb2/ ! common/b/cb +! common//t,w,u,v !end diff --git a/flang/test/Semantics/resolve102.f90 b/flang/test/Semantics/resolve102.f90 --- a/flang/test/Semantics/resolve102.f90 +++ b/flang/test/Semantics/resolve102.f90 @@ -9,7 +9,7 @@ end subroutine subroutine circular - !ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'sub', 'p', 'p2' + !ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p', 'sub', 'p2' procedure(sub) :: p call p(sub) @@ -21,7 +21,7 @@ end subroutine circular program iface - !ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'sub', 'p', 'p2' + !ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p', 'sub', 'p2' procedure(sub) :: p interface subroutine sub(p2) @@ -38,7 +38,7 @@ Call p(sub) contains - !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'p', 'arg' + !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'sub1', 'arg' Subroutine sub1(arg) procedure(sub1) :: arg End Subroutine @@ -54,7 +54,7 @@ Call p(sub) contains - !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'sub', 'p', 'arg', 'p2' + !ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'sub1', 'arg', 'sub', 'p2' Subroutine sub1(arg) procedure(sub) :: arg End Subroutine @@ -68,6 +68,7 @@ !ERROR: The interface for procedure 'p1' is recursively defined !ERROR: The interface for procedure 'p2' is recursively defined procedure(p1) p2 + !ERROR: 'p2' must be an abstract interface or a procedure with an explicit interface procedure(p2) p1 call p1 call p2 @@ -75,8 +76,10 @@ program threeCycle !ERROR: The interface for procedure 'p1' is recursively defined + !ERROR: 'p1' must be an abstract interface or a procedure with an explicit interface !ERROR: The interface for procedure 'p2' is recursively defined procedure(p1) p2 + !ERROR: 'p2' must be an abstract interface or a procedure with an explicit interface !ERROR: The interface for procedure 'p3' is recursively defined procedure(p2) p3 procedure(p3) p1 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 @@ -231,7 +231,7 @@ subroutine s1(x) !CHECK: .b.t.1.allocatable, SAVE, TARGET: ObjectEntity type: TYPE(value) shape: 0_8:1_8,0_8:0_8 init:reshape([value::value(genre=1_1,value=0_8),value(genre=1_1,value=0_8)],shape=[2,1]) !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=.b.t.1.allocatable,initialization=NULL()),component(name=.n.automatic,genre=4_1,category=1_1,kind=4_1,rank=1_1,offset=48_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=.b.t.1.automatic,initialization=NULL()),component(name=.n.chauto,genre=4_1,category=3_1,kind=1_1,rank=0_1,offset=96_8,characterlen=value(genre=3_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=120_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=target)] +!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=.b.t.1.allocatable,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()),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.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=target)] !CHECK: .dt.t.1, SAVE, TARGET: ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=144_8,parent=NULL(),uninstantiated=.dt.t,kindparameter=NULL(),lenparameterkind=.lpk.t.1,component=.c.t.1,procptr=NULL(),special=NULL()) !CHECK: .lpk.t.1, SAVE, TARGET: ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::8_1] type(t(*)), intent(in) :: x diff --git a/flang/unittests/Evaluate/intrinsics.cpp b/flang/unittests/Evaluate/intrinsics.cpp --- a/flang/unittests/Evaluate/intrinsics.cpp +++ b/flang/unittests/Evaluate/intrinsics.cpp @@ -24,7 +24,7 @@ offsets_[s] = cooked_.Put(s); cooked_.PutProvenance(allSources_.AddCompilerInsertion(s)); } - void Marshal() { cooked_.Marshal(allSources_); } + void Marshal() { cooked_.Marshal(allCookedSources_); } parser::CharBlock operator()(const std::string &s) { return {cooked_.AsCharBlock().begin() + offsets_[s], s.size()}; }