Skip to content

tests: Test line debuginfo for linebreaked function parameters #143880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Enselic
Copy link
Member

@Enselic Enselic commented Jul 13, 2025

Closes #45010 which just E-needs-test.

To verify that this is actually a regression test, do this, which is a simplified and adapted version of what compiletest does for 1.39 and then 1.88:

for toolchain in 1.39 1.88; do
    echo -e "\nWith $toolchain:"
    rustc +$toolchain "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--emit" "llvm-ir" "-o" "/tmp/fn-parameters-on-different-lines-debuginfo.ll"  "-g" "-Copt-level=0"
    "build/x86_64-unknown-linux-gnu/ci-llvm/bin/FileCheck" "--input-file" "/tmp/fn-parameters-on-different-lines-debuginfo.ll" "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--check-prefix=CHECK" "--dump-input-context" "100" && echo OK || echo FAIL
done

which gives

With 1.39:
FAIL

With 1.88:
OK
Click to expand full output
$ for toolchain in 1.39 1.88; do
    echo -e "\nWith $toolchain:"
    rustc +$toolchain "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--emit" "llvm-ir" "-o" "/tmp/fn-parameters-on-different-lines-debuginfo.ll"  "-g" "-Copt-level=0"
    "build/x86_64-unknown-linux-gnu/ci-llvm/bin/FileCheck" "--input-file" "/tmp/fn-parameters-on-different-lines-debuginfo.ll" "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--check-prefix=CHECK" "--dump-input-context" "100" && echo OK || echo FAIL
done


With 1.39:
tests/codegen/fn-parameters-on-different-lines-debuginfo.rs:16:16: error: CHECK-SAME: expected string not found in input
// CHECK-SAME: line: 10
               ^
/tmp/fn-parameters-on-different-lines-debuginfo.ll:69:42: note: scanning from here
!10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !3, line: 1, type: !9)
                                         ^
/tmp/fn-parameters-on-different-lines-debuginfo.ll:69:64: note: possible intended match here
!10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !3, line: 1, type: !9)
                                                               ^

Input file: /tmp/fn-parameters-on-different-lines-debuginfo.ll
Check file: tests/codegen/fn-parameters-on-different-lines-debuginfo.rs

-dump-input=help explains the following input dump.

Input was:
<<<<<<
           1: ; ModuleID = 'fn_parameters_on_different_lines_debuginfo.3a1fbbbh-cgu.0'
           2: source_filename = "fn_parameters_on_different_lines_debuginfo.3a1fbbbh-cgu.0"
           3: target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
           4: target triple = "x86_64-unknown-linux-gnu"
           5:
           6: @str.0 = internal constant [59 x i8] c"tests/codegen/fn-parameters-on-different-lines-debuginfo.rs"
           7: @str.1 = internal constant [28 x i8] c"attempt to add with overflow"
           8: @panic_loc.2 = private unnamed_addr constant { { [0 x i8]*, i64 }, { [0 x i8]*, i64 }, i32, i32 } { { [0 x i8]*, i64 } { [0 x i8]* bitcast ([28 x i8]* @str.1 to [0 x i8]*), i64 28 }, { [0 x i8]*, i64 } { [0 x i8]* bitcast ([59 x i8]* @str.0 to [0 x i8]*), i64 59 }, i32 13, i32 3 }, align 8
           9: @__rustc_debug_gdb_scripts_section__ = linkonce_odr unnamed_addr constant [34 x i8] c"\01gdb_load_rust_pretty_printers.py\00", section ".debug_gdb_scripts", align 1
          10:
          11: ; fn_parameters_on_different_lines_debuginfo::foo
          12: ; Function Attrs: nonlazybind uwtable
          13: define i32 @_ZN42fn_parameters_on_different_lines_debuginfo3foo17ha98e7c29f4ed8d60E(i32, i32) unnamed_addr #0 !dbg !5 {
          14: start:
          15:  %y = alloca i32, align 4
          16:  %x = alloca i32, align 4
          17:  store i32 %0, i32* %x, align 4
          18:  call void @llvm.dbg.declare(metadata i32* %x, metadata !10, metadata !DIExpression()), !dbg !11
          19:  store i32 %1, i32* %y, align 4
          20:  call void @llvm.dbg.declare(metadata i32* %y, metadata !12, metadata !DIExpression()), !dbg !11
          21:  %2 = load i32, i32* %x, align 4, !dbg !13
          22:  %3 = load i32, i32* %y, align 4, !dbg !14
          23:  %4 = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %2, i32 %3), !dbg !13
          24:  %5 = extractvalue { i32, i1 } %4, 0, !dbg !13
          25:  %6 = extractvalue { i32, i1 } %4, 1, !dbg !13
          26:  %7 = call i1 @llvm.expect.i1(i1 %6, i1 false), !dbg !13
          27:  br i1 %7, label %panic, label %bb1, !dbg !13
          28:
          29: bb1: ; preds = %start
          30:  ret i32 %5, !dbg !15
          31:
          32: panic: ; preds = %start
          33: ; call core::panicking::panic
          34:  call void @_ZN4core9panicking5panic17h2f49f09cf859b728E({ [0 x i64], { [0 x i8]*, i64 }, [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }* noalias readonly align 8 dereferenceable(40) bitcast ({ { [0 x i8]*, i64 }, { [0 x i8]*, i64 }, i32, i32 }* @panic_loc.2 to { [0 x i64], { [0 x i8]*, i64 }, [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }*)), !dbg !13
          35:  unreachable, !dbg !13
          36: }
          37:
          38: ; Function Attrs: nounwind readnone speculatable
          39: declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
          40:
          41: ; Function Attrs: nounwind readnone speculatable
          42: declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #1
          43:
          44: ; Function Attrs: nounwind readnone
          45: declare i1 @llvm.expect.i1(i1, i1) #2
          46:
          47: ; core::panicking::panic
          48: ; Function Attrs: cold noinline noreturn nonlazybind uwtable
          49: declare void @_ZN4core9panicking5panic17h2f49f09cf859b728E({ [0 x i64], { [0 x i8]*, i64 }, [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }* noalias readonly align 8 dereferenceable(40)) unnamed_addr #3
          50:
          51: attributes #0 = { nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }
          52: attributes #1 = { nounwind readnone speculatable }
          53: attributes #2 = { nounwind readnone }
          54: attributes #3 = { cold noinline noreturn nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }
          55:
          56: !llvm.module.flags = !{!0, !1}
          57: !llvm.dbg.cu = !{!2}
          58:
          59: !0 = !{i32 2, !"RtLibUseGOT", i32 1}
          60: !1 = !{i32 2, !"Debug Info Version", i32 3}
          61: !2 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !3, producer: "clang LLVM (rustc version 1.39.0 (4560ea788 2019-11-04))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4)
          62: !3 = !DIFile(filename: "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs", directory: "/home/martin/src/rust")
          63: !4 = !{}
          64: !5 = distinct !DISubprogram(name: "foo", linkageName: "_ZN42fn_parameters_on_different_lines_debuginfo3foo17ha98e7c29f4ed8d60E", scope: !6, file: !3, line: 9, type: !7, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, templateParams: !4, retainedNodes: !4)
          65: !6 = !DINamespace(name: "fn_parameters_on_different_lines_debuginfo", scope: null)
          66: !7 = !DISubroutineType(types: !8)
          67: !8 = !{!9, !9, !9}
          68: !9 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
          69: !10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !3, line: 1, type: !9)
same:16'0                                              X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
same:16'1                                                                    ?                   possible intended match
          70: !11 = !DILocation(line: 1, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          71: !12 = !DILocalVariable(name: "y", arg: 2, scope: !5, file: !3, line: 1, type: !9)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          72: !13 = !DILocation(line: 13, column: 2, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          73: !14 = !DILocation(line: 13, column: 6, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          74: !15 = !DILocation(line: 13, column: 9, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>
FAIL

With 1.88:
OK

@rustbot
Copy link
Collaborator

rustbot commented Jul 13, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 13, 2025
@Mark-Simulacrum
Copy link
Member

@bors r+

@bors
Copy link
Collaborator

bors commented Jul 13, 2025

📌 Commit 7d2e06a has been approved by Mark-Simulacrum

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 13, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 13, 2025
…-lines-debuginfo, r=Mark-Simulacrum

tests: Test line debuginfo for linebreaked function parameters

Closes rust-lang#45010 which just [E-needs-test](rust-lang#45010 (comment)).

To verify that this is actually a regression test, do this, which is a simplified and adapted version of what compiletest does for 1.39 and then 1.88:

```sh
for toolchain in 1.39 1.88; do
    echo -e "\nWith $toolchain:"
    rustc +$toolchain "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--emit" "llvm-ir" "-o" "/tmp/fn-parameters-on-different-lines-debuginfo.ll"  "-g" "-Copt-level=0"
    "build/x86_64-unknown-linux-gnu/ci-llvm/bin/FileCheck" "--input-file" "/tmp/fn-parameters-on-different-lines-debuginfo.ll" "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--check-prefix=CHECK" "--dump-input-context" "100" && echo OK || echo FAIL
done
```

which gives

```
With 1.39:
FAIL

With 1.88:
OK
```

<details>
<summary>Click to expand full output</summary>

```
$ for toolchain in 1.39 1.88; do
    echo -e "\nWith $toolchain:"
    rustc +$toolchain "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--emit" "llvm-ir" "-o" "/tmp/fn-parameters-on-different-lines-debuginfo.ll"  "-g" "-Copt-level=0"
    "build/x86_64-unknown-linux-gnu/ci-llvm/bin/FileCheck" "--input-file" "/tmp/fn-parameters-on-different-lines-debuginfo.ll" "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs" "--check-prefix=CHECK" "--dump-input-context" "100" && echo OK || echo FAIL
done

With 1.39:
tests/codegen/fn-parameters-on-different-lines-debuginfo.rs:16:16: error: CHECK-SAME: expected string not found in input
// CHECK-SAME: line: 10
               ^
/tmp/fn-parameters-on-different-lines-debuginfo.ll:69:42: note: scanning from here
!10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !3, line: 1, type: !9)
                                         ^
/tmp/fn-parameters-on-different-lines-debuginfo.ll:69:64: note: possible intended match here
!10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !3, line: 1, type: !9)
                                                               ^

Input file: /tmp/fn-parameters-on-different-lines-debuginfo.ll
Check file: tests/codegen/fn-parameters-on-different-lines-debuginfo.rs

-dump-input=help explains the following input dump.

Input was:
<<<<<<
           1: ; ModuleID = 'fn_parameters_on_different_lines_debuginfo.3a1fbbbh-cgu.0'
           2: source_filename = "fn_parameters_on_different_lines_debuginfo.3a1fbbbh-cgu.0"
           3: target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
           4: target triple = "x86_64-unknown-linux-gnu"
           5:
           6: `@str.0` = internal constant [59 x i8] c"tests/codegen/fn-parameters-on-different-lines-debuginfo.rs"
           7: `@str.1` = internal constant [28 x i8] c"attempt to add with overflow"
           8: `@panic_loc.2` = private unnamed_addr constant { { [0 x i8]*, i64 }, { [0 x i8]*, i64 }, i32, i32 } { { [0 x i8]*, i64 } { [0 x i8]* bitcast ([28 x i8]* `@str.1` to [0 x i8]*), i64 28 }, { [0 x i8]*, i64 } { [0 x i8]* bitcast ([59 x i8]* `@str.0` to [0 x i8]*), i64 59 }, i32 13, i32 3 }, align 8
           9: `@__rustc_debug_gdb_scripts_section__` = linkonce_odr unnamed_addr constant [34 x i8] c"\01gdb_load_rust_pretty_printers.py\00", section ".debug_gdb_scripts", align 1
          10:
          11: ; fn_parameters_on_different_lines_debuginfo::foo
          12: ; Function Attrs: nonlazybind uwtable
          13: define i32 `@_ZN42fn_parameters_on_different_lines_debuginfo3foo17ha98e7c29f4ed8d60E(i32,` i32) unnamed_addr #0 !dbg !5 {
          14: start:
          15:  %y = alloca i32, align 4
          16:  %x = alloca i32, align 4
          17:  store i32 %0, i32* %x, align 4
          18:  call void `@llvm.dbg.declare(metadata` i32* %x, metadata !10, metadata !DIExpression()), !dbg !11
          19:  store i32 %1, i32* %y, align 4
          20:  call void `@llvm.dbg.declare(metadata` i32* %y, metadata !12, metadata !DIExpression()), !dbg !11
          21:  %2 = load i32, i32* %x, align 4, !dbg !13
          22:  %3 = load i32, i32* %y, align 4, !dbg !14
          23:  %4 = call { i32, i1 } `@llvm.sadd.with.overflow.i32(i32` %2, i32 %3), !dbg !13
          24:  %5 = extractvalue { i32, i1 } %4, 0, !dbg !13
          25:  %6 = extractvalue { i32, i1 } %4, 1, !dbg !13
          26:  %7 = call i1 `@llvm.expect.i1(i1` %6, i1 false), !dbg !13
          27:  br i1 %7, label %panic, label %bb1, !dbg !13
          28:
          29: bb1: ; preds = %start
          30:  ret i32 %5, !dbg !15
          31:
          32: panic: ; preds = %start
          33: ; call core::panicking::panic
          34:  call void `@_ZN4core9panicking5panic17h2f49f09cf859b728E({` [0 x i64], { [0 x i8]*, i64 }, [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }* noalias readonly align 8 dereferenceable(40) bitcast ({ { [0 x i8]*, i64 }, { [0 x i8]*, i64 }, i32, i32 }* `@panic_loc.2` to { [0 x i64], { [0 x i8]*, i64 }, [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }*)), !dbg !13
          35:  unreachable, !dbg !13
          36: }
          37:
          38: ; Function Attrs: nounwind readnone speculatable
          39: declare void `@llvm.dbg.declare(metadata,` metadata, metadata) #1
          40:
          41: ; Function Attrs: nounwind readnone speculatable
          42: declare { i32, i1 } `@llvm.sadd.with.overflow.i32(i32,` i32) #1
          43:
          44: ; Function Attrs: nounwind readnone
          45: declare i1 `@llvm.expect.i1(i1,` i1) rust-lang#2
          46:
          47: ; core::panicking::panic
          48: ; Function Attrs: cold noinline noreturn nonlazybind uwtable
          49: declare void `@_ZN4core9panicking5panic17h2f49f09cf859b728E({` [0 x i64], { [0 x i8]*, i64 }, [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }* noalias readonly align 8 dereferenceable(40)) unnamed_addr rust-lang#3
          50:
          51: attributes #0 = { nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }
          52: attributes #1 = { nounwind readnone speculatable }
          53: attributes rust-lang#2 = { nounwind readnone }
          54: attributes rust-lang#3 = { cold noinline noreturn nonlazybind uwtable "probe-stack"="__rust_probestack" "target-cpu"="x86-64" }
          55:
          56: !llvm.module.flags = !{!0, !1}
          57: !llvm.dbg.cu = !{!2}
          58:
          59: !0 = !{i32 2, !"RtLibUseGOT", i32 1}
          60: !1 = !{i32 2, !"Debug Info Version", i32 3}
          61: !2 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !3, producer: "clang LLVM (rustc version 1.39.0 (4560ea7 2019-11-04))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4)
          62: !3 = !DIFile(filename: "tests/codegen/fn-parameters-on-different-lines-debuginfo.rs", directory: "/home/martin/src/rust")
          63: !4 = !{}
          64: !5 = distinct !DISubprogram(name: "foo", linkageName: "_ZN42fn_parameters_on_different_lines_debuginfo3foo17ha98e7c29f4ed8d60E", scope: !6, file: !3, line: 9, type: !7, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, templateParams: !4, retainedNodes: !4)
          65: !6 = !DINamespace(name: "fn_parameters_on_different_lines_debuginfo", scope: null)
          66: !7 = !DISubroutineType(types: !8)
          67: !8 = !{!9, !9, !9}
          68: !9 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
          69: !10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !3, line: 1, type: !9)
same:16'0                                              X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
same:16'1                                                                    ?                   possible intended match
          70: !11 = !DILocation(line: 1, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          71: !12 = !DILocalVariable(name: "y", arg: 2, scope: !5, file: !3, line: 1, type: !9)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          72: !13 = !DILocation(line: 13, column: 2, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          73: !14 = !DILocation(line: 13, column: 6, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          74: !15 = !DILocation(line: 13, column: 9, scope: !5)
same:16'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>
FAIL

With 1.88:
OK
```

<details>
bors added a commit that referenced this pull request Jul 13, 2025
Rollup of 8 pull requests

Successful merges:

 - #142885 (core: Add `BorrowedCursor::with_unfilled_buf`)
 - #143217 (Port #[link_ordinal] to the new attribute parsing infrastructure)
 - #143355 (wrapping shift: remove first bitmask and table)
 - #143448 (remote-test-client: Exit code `128 + <signal-number>` instead of `3`)
 - #143724 (Tidy cleanup)
 - #143820 (Fixed a core crate compilation failure when enabling the `optimize_for_size` feature on some targets)
 - #143850 (Compiletest: Simplify {Html,Json}DocCk directive handling)
 - #143880 (tests: Test line debuginfo for linebreaked function parameters)

Failed merges:

 - #143630 (Drop `./x suggest`)
 - #143733 (Change bootstrap's `tool.TOOL_NAME.features` to work on any subcommand)

r? `@ghost`
`@rustbot` modify labels: rollup
@matthiaskrgr
Copy link
Member

@bors r-

#143899 (comment)

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jul 13, 2025
@Enselic Enselic force-pushed the fn-parameters-on-different-lines-debuginfo branch from 7d2e06a to 500b743 Compare July 14, 2025 05:13
@Enselic
Copy link
Member Author

Enselic commented Jul 14, 2025

Turns out wasm32-wasip1 optimizes away the function despite -Copt-level=0. Invoke the function from main() to avoid optimizing it away. I have confirmed that the test still fails with 1.39. Also avoid conflicts with std by renaming the parameters.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DW_TAG_formal_parameter always has DW_AT_decl_line == 1
5 participants