Commit 05d8f1d1 authored by David Chase's avatar David Chase

cmd/compile: propagate correct line numbers in treecopy

Added a lineno parameter to treecopy and listtreecopy
(ignored if = 0).  When nodes are copied the copy is
assigned the non-zero lineno (normally this would be
the destination).

Fixes #8183

Change-Id: Iffb767a745093fb89aa08bf8a7692c2f0122be98
Reviewed-on: https://go-review.googlesource.com/10334Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 21500012
...@@ -313,18 +313,19 @@ func variter(vl *NodeList, t *Node, el *NodeList) *NodeList { ...@@ -313,18 +313,19 @@ func variter(vl *NodeList, t *Node, el *NodeList) *NodeList {
* new_name_list [[type] = expr_list] * new_name_list [[type] = expr_list]
*/ */
func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
lno := int32(0) // default is to leave line number alone in listtreecopy
if cl == nil { if cl == nil {
if t != nil { if t != nil {
Yyerror("const declaration cannot have type without expression") Yyerror("const declaration cannot have type without expression")
} }
cl = lastconst cl = lastconst
t = lasttype t = lasttype
lno = vl.N.Lineno
} else { } else {
lastconst = cl lastconst = cl
lasttype = t lasttype = t
} }
cl = listtreecopy(cl, lno)
cl = listtreecopy(cl)
var v *Node var v *Node
var c *Node var c *Node
......
...@@ -498,7 +498,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -498,7 +498,7 @@ func orderstmt(n *Node, order *Order) {
orderexpr(&n.Left, order, nil) orderexpr(&n.Left, order, nil)
n.Left = ordersafeexpr(n.Left, order) n.Left = ordersafeexpr(n.Left, order)
tmp1 := treecopy(n.Left) tmp1 := treecopy(n.Left, 0)
if tmp1.Op == OINDEXMAP { if tmp1.Op == OINDEXMAP {
tmp1.Etype = 0 // now an rvalue not an lvalue tmp1.Etype = 0 // now an rvalue not an lvalue
} }
......
...@@ -483,7 +483,7 @@ func callinstr(np **Node, init **NodeList, wr int, skip int) bool { ...@@ -483,7 +483,7 @@ func callinstr(np **Node, init **NodeList, wr int, skip int) bool {
*np = n *np = n
} }
n = treecopy(n) n = treecopy(n, 0)
makeaddable(n) makeaddable(n)
var f *Node var f *Node
if t.Etype == TSTRUCT || Isfixedarray(t) { if t.Etype == TSTRUCT || Isfixedarray(t) {
......
...@@ -736,7 +736,12 @@ func aindex(b *Node, t *Type) *Type { ...@@ -736,7 +736,12 @@ func aindex(b *Node, t *Type) *Type {
return r return r
} }
func treecopy(n *Node) *Node { // treecopy recursively copies n, with the exception of
// ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves.
// Copies of iota ONONAME nodes are assigned the current
// value of iota_. If lineno != 0, it sets the line number
// of newly allocated nodes to lineno.
func treecopy(n *Node, lineno int32) *Node {
if n == nil { if n == nil {
return nil return nil
} }
...@@ -747,9 +752,12 @@ func treecopy(n *Node) *Node { ...@@ -747,9 +752,12 @@ func treecopy(n *Node) *Node {
m = Nod(OXXX, nil, nil) m = Nod(OXXX, nil, nil)
*m = *n *m = *n
m.Orig = m m.Orig = m
m.Left = treecopy(n.Left) m.Left = treecopy(n.Left, lineno)
m.Right = treecopy(n.Right) m.Right = treecopy(n.Right, lineno)
m.List = listtreecopy(n.List) m.List = listtreecopy(n.List, lineno)
if lineno != -1 {
m.Lineno = lineno
}
if m.Defn != nil { if m.Defn != nil {
panic("abort") panic("abort")
} }
...@@ -764,6 +772,9 @@ func treecopy(n *Node) *Node { ...@@ -764,6 +772,9 @@ func treecopy(n *Node) *Node {
*m = *n *m = *n
m.Iota = iota_ m.Iota = iota_
if lineno != 0 {
m.Lineno = lineno
}
break break
} }
fallthrough fallthrough
...@@ -3092,10 +3103,10 @@ func Simsimtype(t *Type) int { ...@@ -3092,10 +3103,10 @@ func Simsimtype(t *Type) int {
return et return et
} }
func listtreecopy(l *NodeList) *NodeList { func listtreecopy(l *NodeList, lineno int32) *NodeList {
var out *NodeList var out *NodeList
for ; l != nil; l = l.Next { for ; l != nil; l = l.Next {
out = list(out, treecopy(l.N)) out = list(out, treecopy(l.N, lineno))
} }
return out return out
} }
......
// errorcheck
// Copyright 2015 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.
// Tests correct reporting of line numbers for errors involving iota,
// Issue #8183.
package foo
const (
ok = byte(iota + 253)
bad
barn
bard // ERROR "constant 256 overflows byte"
)
const (
c = len([1 - iota]int{})
d
e // ERROR "array bound must be non-negative" "const initializer len\(composite literal\) is not a constant"
f // ERROR "array bound must be non-negative" "const initializer len\(composite literal\) is not a constant"
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment