diff --git a/spec/compiler/codegen/cast_spec.cr b/spec/compiler/codegen/cast_spec.cr index 104de1b0562d13d1176f59f8954ba959f04dedb8..cb963efa18fc37a3d5e1c349f592746937512a0e 100644 --- a/spec/compiler/codegen/cast_spec.cr +++ b/spec/compiler/codegen/cast_spec.cr @@ -242,4 +242,33 @@ describe "Code gen: cast" do x.to_i )).to_i.should eq(1) end + + it "allows casting nil to Void*" do + run(%( + (nil as Void*).address + )).to_i.should eq(0) + end + + it "allows casting nilable type to Void* (1)" do + run(%( + a = 1 == 1 ? Reference.new : nil + (a as Void*).address + )).to_i.should_not eq(0) + end + + it "allows casting nilable type to Void* (2)" do + run(%( + a = 1 == 2 ? Reference.new : nil + (a as Void*).address + )).to_i.should eq(0) + end + + it "allows casting nilable type to Void* (3)" do + run(%( + class Foo + end + a = 1 == 1 ? Reference.new : (1 == 2 ? Foo.new : nil) + (a as Void*).address + )).to_i.should_not eq(0) + end end diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr index 84378eb59dcee687fe0305d176d8b1ed2e847383..cf0fe5875aa028bbdfb9cccace5758e6b2c8c79c 100644 --- a/src/compiler/crystal/codegen/codegen.cr +++ b/src/compiler/crystal/codegen/codegen.cr @@ -789,7 +789,11 @@ module Crystal to_type = node.to.type.instance_type if to_type.pointer? - @last = cast_to last_value, to_type + if obj_type.nil_type? + @last = llvm_type(to_type).null + else + @last = cast_to last_value, to_type + end elsif obj_type.pointer? @last = cast_to last_value, to_type else diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index 923677b2b34bda370e2ec80ae587f0dd60c47740..3958c54502c377a1f2e536f2dbca2b2fa691a2bc 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -2179,6 +2179,10 @@ module Crystal @union_types.last end + def reference_like? + true + end + def to_s(io) not_nil_type.to_s(io) io << "?"