diff --git a/lib/crystal/codegen.rb b/lib/crystal/codegen.rb index 2e57d8c29e6d3976d3b6d3a48c6f83b3547c3c49..7c865888930cb2eb77ba529d3c54e05afbbaa4a7 100644 --- a/lib/crystal/codegen.rb +++ b/lib/crystal/codegen.rb @@ -753,7 +753,9 @@ module Crystal def visit_struct_set(node) ptr = gep llvm_self, 0, @type.index_of_var(node.name) @last = @vars['value'][:ptr] - @builder.store @last, ptr + value = @last + value = @builder.load @last if node.type.c_struct? || node.type.c_union? + @builder.store value, ptr end def visit_union_alloc(node) diff --git a/spec/codegen/c_struct_spec.rb b/spec/codegen/c_struct_spec.rb index 3a28c4f11b8269c26c9754475fef6030843e0f48..bfcc51d50a4526d2260b21e95784618f70cf0981 100644 --- a/spec/codegen/c_struct_spec.rb +++ b/spec/codegen/c_struct_spec.rb @@ -57,4 +57,26 @@ describe 'Code gen: struct' do foo.bar.y )).to_i.should eq(2) end + + it "codegens struct set inside struct" do + run(%q( + lib C + struct Bar + y : Int32 + end + + struct Foo + x : Int32 + bar : Bar + end + end + + foo = C::Foo.new + bar = C::Bar.new + bar.y = 2 + foo.bar = bar + + foo.bar.y + )).to_i.should eq(2) + end end