Index: flang/include/flang/Evaluate/shape.h =================================================================== --- flang/include/flang/Evaluate/shape.h +++ flang/include/flang/Evaluate/shape.h @@ -161,7 +161,7 @@ private: static Result ScalarShape() { return Shape{}; } static Shape ConstantShape(const Constant &); - Result AsShape(ExtentExpr &&) const; + Result AsShapeResult(ExtentExpr &&) const; static Shape CreateShape(int rank, NamedEntity &); template Index: flang/lib/Evaluate/intrinsics.cpp =================================================================== --- flang/lib/Evaluate/intrinsics.cpp +++ flang/lib/Evaluate/intrinsics.cpp @@ -1512,7 +1512,7 @@ if (auto shape{GetShape(context, *arg)}) { if (auto constShape{AsConstantShape(context, *shape)}) { shapeArgSize = constShape->At(ConstantSubscripts{1}).ToInt64(); - CHECK(shapeArgSize >= 0); + CHECK(*shapeArgSize >= 0); argOk = true; } } Index: flang/lib/Evaluate/shape.cpp =================================================================== --- flang/lib/Evaluate/shape.cpp +++ flang/lib/Evaluate/shape.cpp @@ -53,7 +53,7 @@ return result; } -auto GetShapeHelper::AsShape(ExtentExpr &&arrayExpr) const -> Result { +auto GetShapeHelper::AsShapeResult(ExtentExpr &&arrayExpr) const -> Result { if (context_) { arrayExpr = Fold(*context_, std::move(arrayExpr)); } @@ -63,17 +63,17 @@ if (auto *constructor{UnwrapExpr>(arrayExpr)}) { Shape result; for (auto &value : *constructor) { - if (auto *expr{std::get_if(&value.u)}) { - if (expr->Rank() == 0) { - result.emplace_back(std::move(*expr)); - continue; - } + auto *expr{std::get_if(&value.u)}; + if (expr && expr->Rank() == 0) { + result.emplace_back(std::move(*expr)); + } else { + return std::nullopt; } - return std::nullopt; } return result; + } else { + return std::nullopt; } - return std::nullopt; } Shape GetShapeHelper::CreateShape(int rank, NamedEntity &base) { @@ -847,15 +847,6 @@ } } } - } else if (intrinsic->name == "reshape") { - if (call.arguments().size() >= 2 && call.arguments().at(1)) { - // SHAPE(RESHAPE(array,shape)) -> shape - if (const auto *shapeExpr{ - call.arguments().at(1).value().UnwrapExpr()}) { - auto shape{std::get>(shapeExpr->u)}; - return AsShape(ConvertToType(std::move(shape))); - } - } } else if (intrinsic->name == "pack") { if (call.arguments().size() >= 3 && call.arguments().at(2)) { // SHAPE(PACK(,,VECTOR=v)) -> SHAPE(v) @@ -891,6 +882,18 @@ } } } + } else if (intrinsic->name == "reshape") { + if (call.arguments().size() >= 2 && call.arguments().at(1)) { + // SHAPE(RESHAPE(array,shape)) -> shape + if (const auto *shapeExpr{ + call.arguments().at(1).value().UnwrapExpr()}) { + auto shapeArg{std::get>(shapeExpr->u)}; + if (auto result{AsShapeResult( + ConvertToType(std::move(shapeArg)))}) { + return result; + } + } + } } else if (intrinsic->name == "spread") { // SHAPE(SPREAD(ARRAY,DIM,NCOPIES)) = SHAPE(ARRAY) with NCOPIES inserted // at position DIM. @@ -966,7 +969,8 @@ // TODO: shapes of other non-elemental intrinsic results } } - return std::nullopt; + // The rank is always known even if the extents are not. + return Shape(static_cast(call.Rank()), MaybeExtentExpr{}); } // Check conformance of the passed shapes. Index: flang/test/Semantics/call03.f90 =================================================================== --- flang/test/Semantics/call03.f90 +++ flang/test/Semantics/call03.f90 @@ -228,6 +228,7 @@ real :: a(*) !ERROR: Scalar actual argument may not be associated with assumed-shape dummy argument 'x=' call assumedshape(scalar) + call assumedshape(reshape(matrix,shape=[size(matrix)])) ! ok !ERROR: Rank of dummy argument is 1, but actual argument has rank 2 call assumedshape(matrix) !ERROR: Assumed-size array may not be associated with assumed-shape dummy argument 'x='