@@ -899,51 +899,66 @@ template <typename T> Expr<T> Folder<T>::RESHAPE(FunctionRef<T> &&funcRef) {
899899 std::optional<std::vector<ConstantSubscript>> shape{
900900 GetIntegerVector<ConstantSubscript>(args[1 ])};
901901 std::optional<std::vector<int >> order{GetIntegerVector<int >(args[3 ])};
902- if (!source || !shape || (args[2 ] && !pad) || (args[3 ] && !order)) {
903- return Expr<T>{std::move (funcRef)}; // Non-constant arguments
904- } else if (shape.value ().size () > common::maxRank) {
905- context_.messages ().Say (
906- " Size of 'shape=' argument must not be greater than %d" _err_en_US,
907- common::maxRank);
908- } else if (HasNegativeExtent (shape.value ())) {
909- context_.messages ().Say (
910- " 'shape=' argument must not have a negative extent" _err_en_US);
911- } else {
912- std::optional<uint64_t > optResultElement{TotalElementCount (shape.value ())};
913- if (!optResultElement) {
902+ std::optional<uint64_t > optResultElement;
903+ std::optional<std::vector<int >> dimOrder;
904+ bool ok{true };
905+ if (shape) {
906+ if (shape->size () > common::maxRank) {
907+ context_.messages ().Say (
908+ " Size of 'shape=' argument (%zd) must not be greater than %d" _err_en_US,
909+ shape->size (), common::maxRank);
910+ ok = false ;
911+ } else if (HasNegativeExtent (*shape)) {
914912 context_.messages ().Say (
915- " 'shape=' argument has too many elements" _err_en_US);
913+ " 'shape=' argument (%s) must not have a negative extent" _err_en_US,
914+ DEREF (args[1 ]->UnwrapExpr ()).AsFortran ());
915+ ok = false ;
916916 } else {
917- int rank{GetRank (shape.value ())};
918- uint64_t resultElements{*optResultElement};
919- std::optional<std::vector<int >> dimOrder;
920- if (order) {
921- dimOrder = ValidateDimensionOrder (rank, *order);
922- }
923- std::vector<int > *dimOrderPtr{dimOrder ? &dimOrder.value () : nullptr };
924- if (order && !dimOrder) {
917+ optResultElement = TotalElementCount (*shape);
918+ if (!optResultElement) {
925919 context_.messages ().Say (
926- " Invalid 'order=' argument in RESHAPE" _err_en_US);
927- } else if (resultElements > source->size () && (!pad || pad->empty ())) {
920+ " 'shape=' argument (%s) specifies an array with too many elements" _err_en_US,
921+ DEREF (args[1 ]->UnwrapExpr ()).AsFortran ());
922+ ok = false ;
923+ }
924+ }
925+ if (order) {
926+ dimOrder = ValidateDimensionOrder (GetRank (*shape), *order);
927+ if (!dimOrder) {
928928 context_.messages ().Say (
929- " Too few elements in 'source=' argument and 'pad=' "
930- " argument is not present or has null size" _err_en_US);
931- } else {
932- Constant<T> result{!source->empty () || !pad
933- ? source->Reshape (std::move (shape.value ()))
934- : pad->Reshape (std::move (shape.value ()))};
935- ConstantSubscripts subscripts{result.lbounds ()};
936- auto copied{result.CopyFrom (*source,
937- std::min (static_cast <uint64_t >(source->size ()), resultElements),
938- subscripts, dimOrderPtr)};
939- if (copied < resultElements) {
940- CHECK (pad);
941- copied += result.CopyFrom (
942- *pad, resultElements - copied, subscripts, dimOrderPtr);
943- }
944- CHECK (copied == resultElements);
945- return Expr<T>{std::move (result)};
929+ " Invalid 'order=' argument (%s) in RESHAPE" _err_en_US,
930+ DEREF (args[3 ]->UnwrapExpr ()).AsFortran ());
931+ ok = false ;
932+ }
933+ }
934+ }
935+ if (!ok) {
936+ // convert into an invalid intrinsic procedure call below
937+ } else if (!source || !shape || (args[2 ] && !pad) || (args[3 ] && !order)) {
938+ return Expr<T>{std::move (funcRef)}; // Non-constant arguments
939+ } else {
940+ uint64_t resultElements{*optResultElement};
941+ std::vector<int > *dimOrderPtr{dimOrder ? &dimOrder.value () : nullptr };
942+ if (resultElements > source->size () && (!pad || pad->empty ())) {
943+ context_.messages ().Say (
944+ " Too few elements in 'source=' argument and 'pad=' "
945+ " argument is not present or has null size" _err_en_US);
946+ ok = false ;
947+ } else {
948+ Constant<T> result{!source->empty () || !pad
949+ ? source->Reshape (std::move (shape.value ()))
950+ : pad->Reshape (std::move (shape.value ()))};
951+ ConstantSubscripts subscripts{result.lbounds ()};
952+ auto copied{result.CopyFrom (*source,
953+ std::min (static_cast <uint64_t >(source->size ()), resultElements),
954+ subscripts, dimOrderPtr)};
955+ if (copied < resultElements) {
956+ CHECK (pad);
957+ copied += result.CopyFrom (
958+ *pad, resultElements - copied, subscripts, dimOrderPtr);
946959 }
960+ CHECK (copied == resultElements);
961+ return Expr<T>{std::move (result)};
947962 }
948963 }
949964 // Invalid, prevent re-folding
@@ -1398,7 +1413,8 @@ AsFlatArrayConstructor(const Expr<SomeKind<CAT>> &expr) {
13981413template <typename T>
13991414std::optional<Expr<T>> FromArrayConstructor (
14001415 FoldingContext &context, ArrayConstructor<T> &&values, const Shape &shape) {
1401- if (auto constShape{AsConstantExtents (context, shape)}) {
1416+ if (auto constShape{AsConstantExtents (context, shape)};
1417+ constShape && !HasNegativeExtent (*constShape)) {
14021418 Expr<T> result{Fold (context, Expr<T>{std::move (values)})};
14031419 if (auto *constant{UnwrapConstantValue<T>(result)}) {
14041420 // Elements and shape are both constant.
0 commit comments