diff --git a/flang/include/flang/Evaluate/variable.h b/flang/include/flang/Evaluate/variable.h --- a/flang/include/flang/Evaluate/variable.h +++ b/flang/include/flang/Evaluate/variable.h @@ -303,16 +303,15 @@ public: CLASS_BOILERPLATE(Substring) - Substring(DataRef &&parent, int kind, - std::optional> &&lower, + Substring(DataRef &&parent, std::optional> &&lower, std::optional> &&upper) - : parent_{std::move(parent)}, kind_{kind} { + : parent_{std::move(parent)} { SetBounds(lower, upper); } - Substring(StaticDataObject::Pointer &&parent, int kind, + Substring(StaticDataObject::Pointer &&parent, std::optional> &&lower, std::optional> &&upper) - : parent_{std::move(parent)}, kind_{kind} { + : parent_{std::move(parent)} { SetBounds(lower, upper); } @@ -322,15 +321,11 @@ Substring &set_upper(Expr &&); const Parent &parent() const { return parent_; } Parent &parent() { return parent_; } - int kind() { return kind_; } int Rank() const; template const A *GetParentIf() const { return std::get_if(&parent_); } - std::optional GetType() const { - return DynamicType(TypeCategory::Character, kind_); - } BaseObject GetBaseObject() const; const Symbol *GetLastSymbol() const; std::optional> LEN() const; @@ -343,7 +338,6 @@ void SetBounds(std::optional> &, std::optional> &); Parent parent_; - int kind_{0}; std::optional lower_, upper_; }; diff --git a/flang/lib/Evaluate/fold-designator.cpp b/flang/lib/Evaluate/fold-designator.cpp --- a/flang/lib/Evaluate/fold-designator.cpp +++ b/flang/lib/Evaluate/fold-designator.cpp @@ -339,12 +339,12 @@ return std::visit( [&](const auto &x) -> std::optional> { using T = typename std::decay_t::Result; - return AsGenericExpr(Designator{Substring{ - ExtractDataRef(std::move(*cExpr)).value(), T::kind, - std::optional>{ - 1 + (offset / T::kind)}, - std::optional>{ - 1 + ((offset + size - 1) / T::kind)}}}); + return AsGenericExpr(Designator{ + Substring{ExtractDataRef(std::move(*cExpr)).value(), + std::optional>{ + 1 + (offset / T::kind)}, + std::optional>{ + 1 + ((offset + size - 1) / T::kind)}}}); }, cExpr->u); } diff --git a/flang/lib/Evaluate/fold.cpp b/flang/lib/Evaluate/fold.cpp --- a/flang/lib/Evaluate/fold.cpp +++ b/flang/lib/Evaluate/fold.cpp @@ -189,11 +189,10 @@ auto upper{Fold(context, substring.upper())}; if (const DataRef * dataRef{substring.GetParentIf()}) { return Substring{FoldOperation(context, DataRef{*dataRef}), - substring.kind(), std::move(lower), std::move(upper)}; + std::move(lower), std::move(upper)}; } else { auto p{*substring.GetParentIf()}; - return Substring{ - std::move(p), substring.kind(), std::move(lower), std::move(upper)}; + return Substring{std::move(p), std::move(lower), std::move(upper)}; } } diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp --- a/flang/lib/Evaluate/variable.cpp +++ b/flang/lib/Evaluate/variable.cpp @@ -563,15 +563,14 @@ std::optional Designator::GetType() const { if constexpr (IsLengthlessIntrinsicType) { return Result::GetType(); + } else if (const Symbol * symbol{GetLastSymbol()}) { + return DynamicType::From(*symbol); } else if constexpr (Result::category == TypeCategory::Character) { - if (const Symbol * symbol{GetLastSymbol()}) { - return DynamicType::From(symbol); - } else if (const Substring * substring{std::get_if(&u)}) { - // Only really needed for character literal substrings - return substring->GetType(); + if (const Substring * substring{std::get_if(&u)}) { + const auto *parent{substring->GetParentIf()}; + CHECK(parent); + return DynamicType{TypeCategory::Character, (*parent)->itemBytes()}; } - } else { - return DynamicType::From(GetLastSymbol()); } return std::nullopt; } diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -785,8 +785,8 @@ if (dynamicType->category() == TypeCategory::Character) { return WrapperHelper(dynamicType->kind(), - Substring{std::move(checked.value()), dynamicType->kind(), - std::move(first), std::move(last)}); + Substring{std::move(checked.value()), std::move(first), + std::move(last)}); } } Say("substring may apply only to CHARACTER"_err_en_US); @@ -826,9 +826,7 @@ staticData->set_alignment(Result::kind) .set_itemBytes(Result::kind) .Push(cp->GetScalarValue().value()); - CHECK(string->GetType()); - Substring substring{std::move(staticData), - string->GetType()->kind(), std::move(lower.value()), + Substring substring{std::move(staticData), std::move(lower.value()), std::move(upper.value())}; return AsGenericExpr( Expr{Designator{std::move(substring)}}); @@ -873,21 +871,28 @@ std::optional ExpressionAnalyzer::AnalyzeSectionSubscript( const parser::SectionSubscript &ss) { - return std::visit(common::visitors{ - [&](const parser::SubscriptTriplet &t) { - return std::make_optional( - Triplet{TripletPart(std::get<0>(t.t)), - TripletPart(std::get<1>(t.t)), - TripletPart(std::get<2>(t.t))}); - }, - [&](const auto &s) -> std::optional { - if (auto subscriptExpr{AsSubscript(Analyze(s))}) { - return Subscript{std::move(*subscriptExpr)}; - } else { - return std::nullopt; - } - }, - }, + return std::visit( + common::visitors{ + [&](const parser::SubscriptTriplet &t) -> std::optional { + const auto &lower{std::get<0>(t.t)}; + const auto &upper{std::get<1>(t.t)}; + const auto &stride{std::get<2>(t.t)}; + auto result{Triplet{ + TripletPart(lower), TripletPart(upper), TripletPart(stride)}}; + if ((lower && !result.lower()) || (upper && !result.upper())) { + return std::nullopt; + } else { + return std::make_optional(result); + } + }, + [&](const auto &s) -> std::optional { + if (auto subscriptExpr{AsSubscript(Analyze(s))}) { + return Subscript{std::move(*subscriptExpr)}; + } else { + return std::nullopt; + } + }, + }, ss.u); }