From e5bf6b95e7890bc9bd1e172412d010d0e2dce7ad Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Tue, 9 Nov 2021 21:52:23 +0800 Subject: [PATCH] Add missing debug locations to constant / class variable read calls (#11417) Fixes #11416. Although the constant read functions have a debug location, for some reason the calls themselves to the read functions do not. This PR adds them. --- spec/compiler/codegen/debug_spec.cr | 19 +++++++++++++++++++ spec/llvm-ir/class-var-read-debug-loc.cr | 19 +++++++++++++++++++ spec/llvm-ir/const-read-debug-loc.cr | 19 +++++++++++++++++++ spec/llvm-ir/test.sh | 6 ++++++ .../virtual-class-var-read-debug-loc.cr | 17 +++++++++++++++++ .../virtual-metaclass-var-read-debug-loc.cr | 17 +++++++++++++++++ src/compiler/crystal/codegen/class_var.cr | 1 + src/compiler/crystal/codegen/codegen.cr | 2 +- src/compiler/crystal/codegen/const.cr | 3 ++- 9 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 spec/llvm-ir/class-var-read-debug-loc.cr create mode 100644 spec/llvm-ir/const-read-debug-loc.cr create mode 100644 spec/llvm-ir/virtual-class-var-read-debug-loc.cr create mode 100644 spec/llvm-ir/virtual-metaclass-var-read-debug-loc.cr diff --git a/spec/compiler/codegen/debug_spec.cr b/spec/compiler/codegen/debug_spec.cr index f4bc044cc09f..cea79125bc9c 100644 --- a/spec/compiler/codegen/debug_spec.cr +++ b/spec/compiler/codegen/debug_spec.cr @@ -252,4 +252,23 @@ describe "Code gen: debug" do LibFoo.foo = ->{ } ), debug: Crystal::Debug::All) end + + it "doesn't fail on constant read calls (#11416)" do + codegen(%( + require "prelude" + + class Foo + def foo + end + end + + def a_foo + Foo.new + end + + THE_FOO.foo + + THE_FOO = a_foo + ), debug: Crystal::Debug::All) + end end diff --git a/spec/llvm-ir/class-var-read-debug-loc.cr b/spec/llvm-ir/class-var-read-debug-loc.cr new file mode 100644 index 000000000000..01517d63d5a6 --- /dev/null +++ b/spec/llvm-ir/class-var-read-debug-loc.cr @@ -0,0 +1,19 @@ +require "prelude" + +class Foo + def foo + @@x + # CHECK: call %String** @"~Bar::x:read" + # CHECK-SAME: !dbg [[LOC:![0-9]+]] + # CHECK: [[LOC]] = !DILocation + # CHECK-SAME: line: [[# @LINE - 4]] + # CHECK-SAME: column: 5 + end + + @@x = "" +end + +class Bar < Foo +end + +Bar.new.foo diff --git a/spec/llvm-ir/const-read-debug-loc.cr b/spec/llvm-ir/const-read-debug-loc.cr new file mode 100644 index 000000000000..49a840b22f77 --- /dev/null +++ b/spec/llvm-ir/const-read-debug-loc.cr @@ -0,0 +1,19 @@ +require "prelude" + +class Foo + def foo + end +end + +def a_foo + Foo.new +end + +THE_FOO.foo +# CHECK: call %Foo** @"~THE_FOO:read"() +# CHECK-SAME: !dbg [[LOC:![0-9]+]] +# CHECK: [[LOC]] = !DILocation +# CHECK-SAME: line: 12 +# CHECK-SAME: column: 1 + +THE_FOO = a_foo diff --git a/spec/llvm-ir/test.sh b/spec/llvm-ir/test.sh index af913059f05a..810dd31bfe1a 100755 --- a/spec/llvm-ir/test.sh +++ b/spec/llvm-ir/test.sh @@ -34,6 +34,12 @@ pushd $BUILD_DIR >/dev/null test argless-initialize-debug-loc.cr "--cross-compile --target x86_64-unknown-linux-gnu --prelude=empty" test proc-pointer-debug-loc.cr "--cross-compile --target x86_64-unknown-linux-gnu --prelude=empty" +test const-read-debug-loc.cr "--cross-compile --target x86_64-unknown-linux-gnu --prelude=empty" + +# #11416 +test class-var-read-debug-loc.cr "--cross-compile --target x86_64-unknown-linux-gnu --prelude=empty" +test virtual-class-var-read-debug-loc.cr "--cross-compile --target x86_64-unknown-linux-gnu --prelude=empty" +test virtual-metaclass-var-read-debug-loc.cr "--cross-compile --target x86_64-unknown-linux-gnu --prelude=empty" test memset.cr "--cross-compile --target i386-apple-darwin --prelude=empty --no-debug" X32 test memset.cr "--cross-compile --target i386-unknown-linux-gnu --prelude=empty --no-debug" X32 diff --git a/spec/llvm-ir/virtual-class-var-read-debug-loc.cr b/spec/llvm-ir/virtual-class-var-read-debug-loc.cr new file mode 100644 index 000000000000..ff19a98fffa6 --- /dev/null +++ b/spec/llvm-ir/virtual-class-var-read-debug-loc.cr @@ -0,0 +1,17 @@ +class Foo + def foo + @@x + # CHECK: call i32* @"~Foo+::x:read" + # CHECK-SAME: !dbg [[LOC:![0-9]+]] + # CHECK: [[LOC]] = !DILocation + # CHECK-SAME: line: [[# @LINE - 4]] + # CHECK-SAME: column: 5 + end + + @@x = 1 +end + +class Bar < Foo +end + +(Foo.new || Bar.new).foo diff --git a/spec/llvm-ir/virtual-metaclass-var-read-debug-loc.cr b/spec/llvm-ir/virtual-metaclass-var-read-debug-loc.cr new file mode 100644 index 000000000000..3c81d23699be --- /dev/null +++ b/spec/llvm-ir/virtual-metaclass-var-read-debug-loc.cr @@ -0,0 +1,17 @@ +class Foo + def self.foo + @@x + # CHECK: call i32* @"~Foo+.class::x:read" + # CHECK-SAME: !dbg [[LOC3:![0-9]+]] + # CHECK: [[LOC3]] = !DILocation + # CHECK-SAME: line: [[# @LINE - 4]] + # CHECK-SAME: column: 5 + end + + @@x = 1 +end + +class Bar < Foo +end + +(Foo || Bar).foo diff --git a/src/compiler/crystal/codegen/class_var.cr b/src/compiler/crystal/codegen/class_var.cr index d2979dcf161d..bd43a2979861 100644 --- a/src/compiler/crystal/codegen/class_var.cr +++ b/src/compiler/crystal/codegen/class_var.cr @@ -166,6 +166,7 @@ class Crystal::CodeGenVisitor end def read_class_var(node : ClassVar) + set_current_debug_location node if @debug.line_numbers? read_class_var(node.var) end diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr index 3b034e00dbf8..49d1688fa225 100644 --- a/src/compiler/crystal/codegen/codegen.cr +++ b/src/compiler/crystal/codegen/codegen.cr @@ -1470,7 +1470,7 @@ module Crystal def visit(node : Path) if const = node.target_const - read_const(const) + read_const(const, node) elsif replacement = node.syntax_replacement accept replacement else diff --git a/src/compiler/crystal/codegen/const.cr b/src/compiler/crystal/codegen/const.cr index 80b91f2b7170..83c4a934e4e7 100644 --- a/src/compiler/crystal/codegen/const.cr +++ b/src/compiler/crystal/codegen/const.cr @@ -190,7 +190,7 @@ class Crystal::CodeGenVisitor end end - def read_const(const) + def read_const(const, node) # We inline constants. Otherwise we use an LLVM const global. @last = case value = const.compile_time_value @@ -205,6 +205,7 @@ class Crystal::CodeGenVisitor when UInt32 then int32(value) when UInt64 then int64(value) else + set_current_debug_location node if @debug.line_numbers? last = read_const_pointer(const) to_lhs last, const.value.type end