@@ -39,13 +39,16 @@ static void CopyAttrs(const semantics::Symbol &src, A &dst,
3939// Shapes of function results and dummy arguments have to have
4040// the same rank, the same deferred dimensions, and the same
4141// values for explicit dimensions when constant.
42- bool ShapesAreCompatible (
43- const Shape &x, const Shape &y, bool *possibleWarning) {
44- if (x.size () != y.size ()) {
42+ bool ShapesAreCompatible (const std::optional<Shape> &x,
43+ const std::optional<Shape> &y, bool *possibleWarning) {
44+ if (!x || !y) {
45+ return !x && !y;
46+ }
47+ if (x->size () != y->size ()) {
4548 return false ;
4649 }
47- auto yIter{y. begin ()};
48- for (const auto &xDim : x) {
50+ auto yIter{y-> begin ()};
51+ for (const auto &xDim : * x) {
4952 const auto &yDim{*yIter++};
5053 if (xDim && yDim) {
5154 if (auto equiv{AreEquivalentInInterface (*xDim, *yDim)}) {
@@ -178,9 +181,11 @@ bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
178181 thatIs, that.AsFortran (), thisIs, AsFortran ());
179182 return false ;
180183 }
181- return omitShapeConformanceCheck ||
182- CheckConformance (messages, shape_, that.shape_ , flags, thisIs, thatIs)
183- .value_or (true /* fail only when nonconformance is known now*/ );
184+ return omitShapeConformanceCheck || (!shape_ && !that.shape_ ) ||
185+ (shape_ && that.shape_ &&
186+ CheckConformance (
187+ messages, *shape_, *that.shape_ , flags, thisIs, thatIs)
188+ .value_or (true /* fail only when nonconformance is known now*/ ));
184189}
185190
186191std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureElementSizeInBytes (
@@ -201,11 +206,11 @@ std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureElementSizeInBytes(
201206
202207std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureSizeInBytes (
203208 FoldingContext &foldingContext) const {
204- if (auto elements{GetSize (Shape{ shape_} )}) {
209+ if (auto elements{GetSize (shape_)}) {
205210 // Sizes of arrays (even with single elements) are multiples of
206211 // their alignments.
207212 if (auto elementBytes{
208- MeasureElementSizeInBytes (foldingContext, GetRank (shape_ ) > 0 )}) {
213+ MeasureElementSizeInBytes (foldingContext, Rank ( ) > 0 )}) {
209214 return Fold (
210215 foldingContext, std::move (*elements) * std::move (*elementBytes));
211216 }
@@ -254,10 +259,12 @@ std::string TypeAndShape::AsFortran() const {
254259llvm::raw_ostream &TypeAndShape::Dump (llvm::raw_ostream &o) const {
255260 o << type_.AsFortran (LEN_ ? LEN_->AsFortran () : " " );
256261 attrs_.Dump (o, EnumToString);
257- if (!shape_.empty ()) {
262+ if (!shape_) {
263+ o << " dimension(..)" ;
264+ } else if (!shape_->empty ()) {
258265 o << " dimension" ;
259266 char sep{' (' };
260- for (const auto &expr : shape_) {
267+ for (const auto &expr : * shape_) {
261268 o << sep;
262269 sep = ' ,' ;
263270 if (expr) {
@@ -1112,6 +1119,7 @@ bool FunctionResult::CanBeReturnedViaImplicitInterface(
11121119
11131120static std::optional<std::string> AreIncompatibleFunctionResultShapes (
11141121 const Shape &x, const Shape &y) {
1122+ // Function results cannot be assumed-rank, hence the non optional arguments.
11151123 int rank{GetRank (x)};
11161124 if (int yrank{GetRank (y)}; yrank != rank) {
11171125 return " rank " s + std::to_string (rank) + " vs " + std::to_string (yrank);
@@ -1147,7 +1155,8 @@ bool FunctionResult::IsCompatibleWith(
11471155 }
11481156 } else if (!attrs.test (Attr::Allocatable) && !attrs.test (Attr::Pointer) &&
11491157 (details = AreIncompatibleFunctionResultShapes (
1150- ifaceTypeShape->shape (), actualTypeShape->shape ()))) {
1158+ ifaceTypeShape->shape ().value (),
1159+ actualTypeShape->shape ().value ()))) {
11511160 if (whyNot) {
11521161 *whyNot = " function results have distinct extents (" + *details + ' )' ;
11531162 }
0 commit comments