From 9b976f5f03689e65c8f58e9b3de94e0d7f7fe072 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 12 May 2014 11:59:55 -0400 Subject: [PATCH] cmd/gc: record line number for auto-generated wrappers as :1 Before we used line 1 of the first source file. This should be clearer. Fixes #4388. LGTM=iant R=golang-codereviews, iant CC=golang-codereviews https://golang.org/cl/92250044 --- src/cmd/gc/subr.c | 4 ++- src/liblink/obj.c | 2 +- test/fixedbugs/issue4388.go | 50 +++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 test/fixedbugs/issue4388.go diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index c7db5e8cd9..23cc9e11f7 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -2498,7 +2498,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) print("genwrapper rcvrtype=%T method=%T newnam=%S\n", rcvr, method, newnam); - lineno = 1; // less confusing than end of input + lexlineno++; + lineno = lexlineno; + linehist("", 0, 0); dclcontext = PEXTERN; markdcl(); diff --git a/src/liblink/obj.c b/src/liblink/obj.c index 53ae470354..b8083b0ec4 100644 --- a/src/liblink/obj.c +++ b/src/liblink/obj.c @@ -183,7 +183,7 @@ linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l) file = a[n].incl->name; dlno = a[n].idel-1; } - if((!ctxt->windows && file[0] == '/') || (ctxt->windows && file[1] == ':')) + if((!ctxt->windows && file[0] == '/') || (ctxt->windows && file[1] == ':') || file[0] == '<') snprint(buf, sizeof buf, "%s", file); else snprint(buf, sizeof buf, "%s/%s", ctxt->pathname, file); diff --git a/test/fixedbugs/issue4388.go b/test/fixedbugs/issue4388.go new file mode 100644 index 0000000000..c8c53b7103 --- /dev/null +++ b/test/fixedbugs/issue4388.go @@ -0,0 +1,50 @@ +// run + +// Copyright 2014 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 ( + "fmt" + "io" + "runtime" +) + +type T struct { + io.Closer +} + +func f1() { + // The 4 here and below depends on the number of internal runtime frames + // that sit between a deferred function called during panic and + // the original frame. If that changes, this test will start failing and + // the number here will need to be updated. + defer checkLine(4) + var t *T + var c io.Closer = t + c.Close() +} + +func f2() { + defer checkLine(4) + var t T + var c io.Closer = t + c.Close() +} + +func main() { + f1() + f2() +} + +func checkLine(n int) { + if err := recover(); err == nil { + panic("did not panic") + } + _, file, line, _ := runtime.Caller(n) + if file != "" || line != 1 { + panic(fmt.Sprintf("expected :1 have %s:%d", file, line)) + } +}