Crystal: Compiler bug in loop with different object types?

Created on 3 Jun 2018  路  3Comments  路  Source: crystal-lang/crystal

Hello,

I am not sure if this issue is similar / same like:
https://github.com/crystal-lang/crystal/issues/4916

From what I can tell, running a loop with different object types reads something incorrectly and receives signal 11:

Invalid memory access (signal 11) at address 0x8
[0x55685aace256] *CallStack::print_backtrace:Int32 +118
[0x55685aac27cb] __crystal_sigfault_handler +75
[0x7fa818e3bdd0] ???
[0x55685aab5bb5] __crystal_main +2101
[0x55685aac2ab6] *_crystal_main<Int32, Pointer(Pointer(UInt8))>:Nil +6
[0x55685ab0f136] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6
[0x55685ab0eff2] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +50
[0x55685aac0b66] main +6
[0x7fa81821af4a] __libc_start_main +234
[0x55685aab529a] _start +42
[0x0] ???

Code to reproduce is on play 47hw, but also included here:

module Base
  getter parent : Base?
end

class Evnt
  getter parent : Base
  def initialize(@parent)
  end
end

class MainObj
  include Base
  property event : Evnt?
end

o = MainObj.new
o.event = Evnt.new(o)

puts "Next two lines of output should be MainObj and Nil"
p o.event.not_nil!.parent.class
p o.parent.class

puts "Next line of output should be MainObj, and program should"
puts "then exit due to condition no longer being true"
puts "But the output is MainObj and MainObj, and program segfaults."
el = o.event.not_nil!
while el = el.parent
  puts el.class
end

Crystal version is 0.24.2 binary tgz build from Crystal website.
Crystal 0.24.2 [4f9ed8d03] (2018-03-08)
LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu

Thanks!

bug compiler

Most helpful comment

Here is a smaller reproducible test case (also on Play: https://play.crystal-lang.org/#/r/4dkk):

class Class1
  property parent : self?
end
class Class2
  # If the following property is optional/nilable (type "Class1?"), program works.
  # If it is not optional (type "Class1"), it segfaults.
  property parent : Class1
  def initialize(@parent) end
end

c1 = Class1.new
c2 = Class2.new(c1)

el = c2.not_nil!
while el = el.parent
  puts el.class
end

All 3 comments

Just for info, the same program converted to Ruby works fine:

module Base
  attr_reader :parent
end

class Evnt
  attr_reader :parent
  def initialize(parent)
    @parent = parent
  end 
end

class MainObj
  include Base
  attr_accessor :event
end

o = MainObj.new
o.event = Evnt.new(o)

puts "Next two lines of output should be MainObj and Nil"
p o.event.parent.class
p o.parent.class

puts "Next line of output should be MainObj, and program should"
puts "then exit due to condition no longer being true"
el = o.event
while el = el.parent
  puts el.class
end

I've checked and the same issue appears on Crystal 0.25.0.

Here is a smaller reproducible test case (also on Play: https://play.crystal-lang.org/#/r/4dkk):

class Class1
  property parent : self?
end
class Class2
  # If the following property is optional/nilable (type "Class1?"), program works.
  # If it is not optional (type "Class1"), it segfaults.
  property parent : Class1
  def initialize(@parent) end
end

c1 = Class1.new
c2 = Class2.new(c1)

el = c2.not_nil!
while el = el.parent
  puts el.class
end
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jhass picture jhass  路  3Comments

Sija picture Sija  路  3Comments

lgphp picture lgphp  路  3Comments

lbguilherme picture lbguilherme  路  3Comments

RX14 picture RX14  路  3Comments