Skip to content

Commit

Permalink
Always use 0 for offset of StaticArray's @buffer (#13319)
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil authored and straight-shoota committed May 8, 2023
1 parent 2447946 commit c148806
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
8 changes: 8 additions & 0 deletions spec/compiler/codegen/offsetof_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,12 @@ describe "Code gen: offsetof" do
(pointerof(f).as(Void*) + offsetof(Foo, @y).to_i64).as(UInt32*).value == f.y
CRYSTAL
end

it "returns offset of `StaticArray#@buffer`" do
run(<<-CRYSTAL).to_b.should be_true
x = uninitialized Int32[4]
pointerof(x.@buffer).value = 12345
(pointerof(x).as(Void*) + offsetof(Int32[4], @buffer).to_i64).as(Int32*).value == x.@buffer
CRYSTAL
end
end
26 changes: 26 additions & 0 deletions spec/compiler/interpreter/pointers_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,32 @@ describe Crystal::Repl::Interpreter do
CRYSTAL
end

it "pointerof read `StaticArray#@buffer` (1)" do
interpret(<<-CRYSTAL).should eq(2)
struct StaticArray(T, N)
def to_unsafe
pointerof(@buffer)
end
def x
@buffer
end
end
foo = uninitialized Int32[4]
foo.to_unsafe.value = 2
foo.x
CRYSTAL
end

it "pointerof read `StaticArray#@buffer` (2)" do
interpret(<<-CRYSTAL).should eq(2)
foo = uninitialized Int32[4]
pointerof(foo.@buffer).value = 2
foo.@buffer
CRYSTAL
end

it "interprets pointer set and get (union type)" do
interpret(<<-CRYSTAL).should eq(10)
ptr = Pointer(Int32 | Bool).malloc(1_u64)
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ module Crystal
end

def offset_of(type, element_index)
return 0_u64 if type.extern_union?
return 0_u64 if type.extern_union? || type.is_a?(StaticArrayInstanceType)
llvm_typer.offset_of(llvm_typer.llvm_type(type), element_index)
end

def instance_offset_of(type, element_index)
# extern unions must be value types, which always use the above
# `offset_of` instead
# extern unions and static arrays must be value types, which always use
# the above `offset_of` instead
llvm_typer.offset_of(llvm_typer.llvm_struct_type(type), element_index + 1)
end
end
Expand Down

0 comments on commit c148806

Please sign in to comment.