diff --git a/flang/lib/evaluate/fold.cc b/flang/lib/evaluate/fold.cc index acd17ebe1d66..ec56acf09d57 100644 --- a/flang/lib/evaluate/fold.cc +++ b/flang/lib/evaluate/fold.cc @@ -445,14 +445,7 @@ Expr> FoldIntrinsicFunction( return j.value; })); } else if (name == "bit_size") { - if (auto *sx{UnwrapExpr>(args[0])}) { - return std::visit( - [](const auto &x) { - using TR = typename std::decay_t::Result; - return Expr{Scalar::bits}; - }, - sx->u); - } + return Expr{Scalar::bits}; } else if (name == "dim") { return FoldElementalIntrinsic( context, std::move(funcRef), &Scalar::DIM); diff --git a/flang/lib/evaluate/intrinsics.cc b/flang/lib/evaluate/intrinsics.cc index 89a65c9e179f..06cc31fd8b22 100644 --- a/flang/lib/evaluate/intrinsics.cc +++ b/flang/lib/evaluate/intrinsics.cc @@ -296,7 +296,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ {{"i", AnyInt, Rank::elementalOrBOZ}, {"j", AnyInt, Rank::elementalOrBOZ}}, DefaultLogical}, - {"bit_size", {{"i", AnyInt, Rank::anyOrAssumedRank}}, DefaultInt, + {"bit_size", {{"i", SameInt, Rank::anyOrAssumedRank}}, SameInt, Rank::scalar}, {"ble", {{"i", AnyInt, Rank::elementalOrBOZ}, diff --git a/flang/lib/evaluate/shape.h b/flang/lib/evaluate/shape.h index 8bb786029fd3..5596b056c345 100644 --- a/flang/lib/evaluate/shape.h +++ b/flang/lib/evaluate/shape.h @@ -56,7 +56,8 @@ std::optional AsConstantExtents(const Shape &); inline int GetRank(const Shape &s) { return static_cast(s.size()); } -// The dimension here is zero-based, unlike DIM= arguments to many intrinsics. +// The dimension argument to these inquiries is zero-based, +// unlike the DIM= arguments to many intrinsics. MaybeExtentExpr GetLowerBound( FoldingContext &, const NamedEntity &, int dimension); Shape GetLowerBounds(FoldingContext &, const NamedEntity &); diff --git a/flang/lib/semantics/resolve-names.cc b/flang/lib/semantics/resolve-names.cc index d204bd791519..9fae3f8ae485 100644 --- a/flang/lib/semantics/resolve-names.cc +++ b/flang/lib/semantics/resolve-names.cc @@ -658,6 +658,7 @@ public: using ScopeHandler::Post; using ScopeHandler::Pre; + bool Pre(const parser::Initialization &); void Post(const parser::EntityDecl &); void Post(const parser::ObjectDecl &); void Post(const parser::PointerDecl &); @@ -2636,6 +2637,13 @@ void DeclarationVisitor::Post(const parser::CodimensionDecl &x) { DeclareObjectEntity(name, Attrs{}); } +bool DeclarationVisitor::Pre(const parser::Initialization &) { + // Defer inspection of initializers to Initialization() so that the + // symbol being initialized will be available within the initialization + // expression. + return false; +} + void DeclarationVisitor::Post(const parser::EntityDecl &x) { // TODO: may be under StructureStmt const auto &name{std::get(x.t)}; @@ -2677,8 +2685,8 @@ bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) { return false; } const auto &expr{std::get(x.t)}; - Walk(expr); ApplyImplicitRules(symbol); + Walk(expr); if (auto converted{ EvaluateConvertedExpr(symbol, expr, expr.thing.value().source)}) { symbol.get().set_init(std::move(*converted)); @@ -4773,6 +4781,10 @@ void DeclarationVisitor::Initialization(const parser::Name &name, if (name.symbol == nullptr) { return; } + // Traversal of the initializer was deferred to here so that the + // symbol being declared can be available for e.g. + // real, parameter :: x = tiny(x) + Walk(init.u); Symbol &ultimate{name.symbol->GetUltimate()}; if (auto *details{ultimate.detailsIf()}) { // TODO: check C762 - all bounds and type parameters of component