Skip to content

Commit abd51f1

Browse files
committed
Fix list.pop() for negative arguments
1 parent 2afa365 commit abd51f1

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

integration_tests/test_list_pop.py

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ def test_list_pop():
44
l1: list[i32]
55
l2: list[tuple[i32, f64]]
66
l3: list[list[str]]
7+
l4: list[i32]
78
i: i32
89
j: i32
910
total: i32
@@ -45,6 +46,10 @@ def test_list_pop():
4546
assert l1.pop(len(l1) - 1) == 4
4647
assert l1 == [1, 2]
4748

49+
l4 = [1, 2, 3, 4, 5]
50+
assert l4.pop(-5) == 1
51+
assert l4.pop(-1) == 5
52+
4853
total = 10
4954
l1 = []
5055
for i in range(total):

src/libasr/codegen/llvm_utils.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -4659,10 +4659,26 @@ namespace LCompilers {
46594659

46604660
llvm::Value* end_point_ptr = get_pointer_to_current_end_point(list);
46614661
llvm::Value* end_point = LLVM::CreateLoad(*builder, end_point_ptr);
4662+
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
4663+
llvm::APInt(32, 0));
4664+
llvm::Value* adjusted_pos = pos;
4665+
llvm::Value* is_negative = builder->CreateICmpSLT(pos, zero);
4666+
llvm::Value* abs_pos = builder->CreateSelect(is_negative,
4667+
builder->CreateNeg(pos),
4668+
pos
4669+
);
4670+
llvm::Value* is_negative_and_in_bounds = builder->CreateAnd(is_negative,
4671+
builder->CreateICmpULE(abs_pos, end_point)
4672+
);
46624673

4674+
// If the index is negative, convert it to the corresponding positive index
4675+
adjusted_pos = builder->CreateSelect(is_negative_and_in_bounds,
4676+
builder->CreateAdd(end_point, pos),
4677+
adjusted_pos
4678+
);
46634679
llvm::AllocaInst *pos_ptr = builder0.CreateAlloca(
46644680
llvm::Type::getInt32Ty(context), nullptr);
4665-
LLVM::CreateStore(*builder, pos, pos_ptr);
4681+
LLVM::CreateStore(*builder, adjusted_pos, pos_ptr);
46664682
llvm::Value* tmp = nullptr;
46674683

46684684
// Get element to return

0 commit comments

Comments
 (0)