From: Peter Klausler Date: Thu, 25 May 2023 23:01:52 +0000 (-0700) Subject: [flang] Don't fold SIZE()/SHAPE() into expression referencing optional dummy arguments X-Git-Tag: upstream/17.0.6~6615 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=71d5a94985c9569467c1ef8a62b8b326ee2036a6;p=platform%2Fupstream%2Fllvm.git [flang] Don't fold SIZE()/SHAPE() into expression referencing optional dummy arguments When computing the shape of an expression at compilation time as part of folding an intrinsic function like SIZE(), don't create an expression that increases a dependence on the presence of an optional dummy argument. Differential Revision: https://reviews.llvm.org/D151737 --- diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp index 6f6baae..c7dcb1c 100644 --- a/flang/lib/Evaluate/shape.cpp +++ b/flang/lib/Evaluate/shape.cpp @@ -805,9 +805,19 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result { if (call.Rank() == 0) { return ScalarShape(); } else if (call.IsElemental()) { - for (const auto &arg : call.arguments()) { - if (arg && arg->Rank() > 0) { - return (*this)(*arg); + // Use the shape of an actual array argument associated with a + // non-OPTIONAL dummy object argument. + if (context_) { + if (auto chars{characteristics::Procedure::FromActuals( + call.proc(), call.arguments(), *context_)}) { + std::size_t j{0}; + for (const auto &arg : call.arguments()) { + if (arg && arg->Rank() > 0 && j < chars->dummyArguments.size() && + !chars->dummyArguments[j].IsOptional()) { + return (*this)(*arg); + } + ++j; + } } } return ScalarShape(); diff --git a/flang/test/Evaluate/elem-shape.f90 b/flang/test/Evaluate/elem-shape.f90 new file mode 100644 index 0000000..623c833 --- /dev/null +++ b/flang/test/Evaluate/elem-shape.f90 @@ -0,0 +1,16 @@ +! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +! Ensure that optional arguments aren't used to fold SIZE() or SHAPE() +module m + contains + subroutine sub(x,y) + real :: x(:), y(:) + optional x + !CHECK: PRINT *, int(size(y,dim=1,kind=8),kind=4) + print *, size(f(x,y)) + end + elemental function f(x,y) + real, intent(in) :: x, y + optional x + f = y + end +end