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,27 @@ } 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; + Descriptor &vectorResult2{vectorDesc2.descriptor()}; + + RTNAME(CshiftVector) + (vectorResult2, *vectorWithLowerBounds, -2, __FILE__, __LINE__); + EXPECT_EQ(vectorResult2.type(), array->type()); + EXPECT_EQ(vectorResult2.rank(), 1); + EXPECT_EQ(vectorResult2.GetDimension(0).LowerBound(), 1); + EXPECT_EQ(vectorResult2.GetDimension(0).Extent(), 6); + EXPECT_EQ(vectorResult2.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(*vectorResult2.ZeroBasedIndexedElement(j), + cshiftExpect5[j]); + } + vectorResult2.Destroy(); + auto boundary{MakeArray( std::vector{3}, std::vector{-1, -2, -3})}; boundary->GetDimension(0).SetLowerBound(9); // shouldn't matter