Skip to content

Don't create copy of variable when reverse indexing with indexing overloaded#3259

Closed
Book-reader wants to merge 1 commit into
c3lang:masterfrom
Book-reader:fix-reverse-indexing-copy
Closed

Don't create copy of variable when reverse indexing with indexing overloaded#3259
Book-reader wants to merge 1 commit into
c3lang:masterfrom
Book-reader:fix-reverse-indexing-copy

Conversation

@Book-reader
Copy link
Copy Markdown
Member

@Book-reader Book-reader commented May 23, 2026

fixes #3258.

Please let me know if there is a better way to do this.

This is what the LLVM IR generated from https://github.com/Book-reader/c3c/blob/aeeb35c46702c79768cc4e8f6332769949a1874f/test/test_suite/overloading/reverse_index.c3t looked like before these changes:

define void @test.main() #0 {
entry:
  %t = alloca %Test, align 8
  %.anon = alloca %Test, align 8
  %.anon2 = alloca %Test, align 8
  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %t, ptr align 8 @.__const, i32 16, i1 false)
  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %.anon, ptr align 8 %t, i32 16, i1 false)
  %0 = call i64 @test.Test.len(ptr %.anon)
  %sub = sub i64 %0, 1
  %1 = call i32 @test.Test.get(ptr %.anon, i64 %sub)
  %2 = call i64 @test.Test.len(ptr %t)
  %sub1 = sub i64 %2, 1
  %3 = call i32 @test.Test.get(ptr %t, i64 %sub1)
  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %.anon2, ptr align 8 %t, i32 16, i1 false)
  %4 = call i64 @test.Test.len(ptr %.anon2)
  %sub3 = sub i64 %4, 1
  %5 = call ptr @test.Test.get_ref(ptr %.anon2, i64 %sub3)
  %6 = call i64 @test.Test.len(ptr %t)
  %sub4 = sub i64 %6, 1
  %7 = call ptr @test.Test.get_ref(ptr %t, i64 %sub4)
  %8 = call i32 (ptr, ...) @printf(ptr @.str, i32 %1, i32 %3, ptr %5, ptr %7)
  ret void
}

It would allocate a new copy of the original value named %.anon* for each reverse-indexing, making &t[^1] return a pointer to a different value each time it was used.

This doesn't affect Lists in most cases because they store their contents on the heap and the pointer to it would be shared between the copies, but appending to a List using arr[^0] = x would not update the length of the original list and could reallocate the array and cause the original List to point to freed memory.

@Book-reader Book-reader changed the title Don't copy variable when reverse indexing with [] or &[] overloaded Don't copy variable when reverse indexing with indexing overloaded May 23, 2026
@Book-reader Book-reader changed the title Don't copy variable when reverse indexing with indexing overloaded Don't create copy of variable when reverse indexing with indexing overloaded May 23, 2026
@lerno
Copy link
Copy Markdown
Collaborator

lerno commented May 24, 2026

This does not quite solve toe problem. What you need to do is get a reference (if possible) to it and then use that instead. I've pushed another fix.

@lerno lerno closed this May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reverse indexing a type with overloaded indexing operators will create & index a copy of the value

2 participants