diff --git a/flang/runtime/transformational.cpp b/flang/runtime/transformational.cpp --- a/flang/runtime/transformational.cpp +++ b/flang/runtime/transformational.cpp @@ -184,7 +184,7 @@ for (SubscriptValue j{0}; j < extent; ++j) { SubscriptValue resultAt{1 + j}; SubscriptValue sourceAt{lb + (j + shift) % extent}; - if (sourceAt < 0) { + if (sourceAt < lb) { sourceAt += extent; } CopyElement(result, &resultAt, source, &sourceAt, terminator); diff --git a/flang/unittests/Runtime/Transformational.cpp b/flang/unittests/Runtime/Transformational.cpp --- a/flang/unittests/Runtime/Transformational.cpp +++ b/flang/unittests/Runtime/Transformational.cpp @@ -93,6 +93,26 @@ } vectorResult.Destroy(); + // VECTOR 1 3 5 2 4 6 WITH non zero lower bound in a negative cshift. + auto vectorWithLowerBounds{MakeArray( + std::vector{6}, std::vector{1, 2, 3, 4, 5, 6})}; + vector->GetDimension(0).SetLowerBound(2); + StaticDescriptor<1, true> vectorDesc2; + + RTNAME(CshiftVector) + (vectorResult, *vectorWithLowerBounds, -2, __FILE__, __LINE__); + EXPECT_EQ(vectorResult.type(), array->type()); + EXPECT_EQ(vectorResult.rank(), 1); + EXPECT_EQ(vectorResult.GetDimension(0).LowerBound(), 1); + EXPECT_EQ(vectorResult.GetDimension(0).Extent(), 6); + EXPECT_EQ(vectorResult.type(), (TypeCode{TypeCategory::Integer, 4})); + static std::int32_t cshiftExpect5[6]{5, 6, 1, 2, 3, 4}; + for (int j{0}; j < 6; ++j) { + EXPECT_EQ(*vectorResult.ZeroBasedIndexedElement(j), + cshiftExpect5[j]); + } + vectorResult.Destroy(); + auto boundary{MakeArray( std::vector{3}, std::vector{-1, -2, -3})}; boundary->GetDimension(0).SetLowerBound(9); // shouldn't matter @@ -130,6 +150,22 @@ eoshiftVectorExpect[j]); } vectorResult.Destroy(); + + // VECTOR EOSHIFT on input with non zero lower bounds + RTNAME(EoshiftVector) + (vectorResult, *vectorWithLowerBounds, -2, &vectorBoundary, __FILE__, + __LINE__); + EXPECT_EQ(vectorResult.type(), array->type()); + EXPECT_EQ(vectorResult.rank(), 1); + EXPECT_EQ(vectorResult.GetDimension(0).LowerBound(), 1); + EXPECT_EQ(vectorResult.GetDimension(0).Extent(), 6); + EXPECT_EQ(vectorResult.type(), (TypeCode{TypeCategory::Integer, 4})); + static std::int32_t eoshiftVectorExpect2[6]{343, 343, 1, 2, 3, 4}; + for (int j{0}; j < 6; ++j) { + EXPECT_EQ(*vectorResult.ZeroBasedIndexedElement(j), + eoshiftVectorExpect2[j]); + } + vectorResult.Destroy(); } TEST(Transformational, Pack) {