-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/compile: copy literals when inlining
Without this, literals keep their original source positions through inlining, which results in strange jumps in line numbers of inlined function bodies. By copying literals, inlining can update their source position like other nodes. Fixes golang#15453. Change-Id: Iad5d9bbfe183883794213266dc30e31bab89ee69 Reviewed-on: https://go-review.googlesource.com/37232 Run-TryBot: David Lazar <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Russ Cox <[email protected]>
- Loading branch information
1 parent
699175a
commit 1c6ef9a
Showing
2 changed files
with
77 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// run | ||
|
||
// Copyright 2017 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package main | ||
|
||
import ( | ||
"log" | ||
"reflect" | ||
"runtime" | ||
) | ||
|
||
func hello() string { | ||
return "Hello World" // line 16 | ||
} | ||
|
||
func foo() string { // line 19 | ||
x := hello() // line 20 | ||
y := hello() // line 21 | ||
return x + y // line 22 | ||
} | ||
|
||
func bar() string { | ||
x := hello() // line 26 | ||
return x | ||
} | ||
|
||
// funcPC returns the PC for the func value f. | ||
func funcPC(f interface{}) uintptr { | ||
return reflect.ValueOf(f).Pointer() | ||
} | ||
|
||
// Test for issue #15453. Previously, line 26 would appear in foo(). | ||
func main() { | ||
pc := funcPC(foo) | ||
f := runtime.FuncForPC(pc) | ||
for ; runtime.FuncForPC(pc) == f; pc++ { | ||
file, line := f.FileLine(pc) | ||
if line == 0 { | ||
continue | ||
} | ||
// Line 16 can appear inside foo() because PC-line table has | ||
// innermost line numbers after inlining. | ||
if line != 16 && !(line >= 19 && line <= 22) { | ||
log.Fatalf("unexpected line at PC=%d: %s:%d\n", pc, file, line) | ||
} | ||
} | ||
} |