mirror of
https://github.com/golang/go
synced 2024-11-26 01:07:57 -07:00
cmd/compile: convert typecheck_stack to []*Node
This one of a set of changes to make the transition away from NodeList easier by removing cases in which NodeList doesn't act semi-trivially like a []*Node. This CL was originally prepared by Josh Bleecher Snyder <josharian@gmail.com>. This change passes go build -toolexec 'toolstash -cmp' -a std. Change-Id: I4d041b343952f4a31f3150fd70669e08fcaa74f8 Reviewed-on: https://go-review.googlesource.com/14305 Run-TryBot: Dave Cheney <dave@cheney.net> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
63e2bed0ab
commit
dab0dac01a
@ -89,33 +89,26 @@ func typekind(t *Type) string {
|
||||
return fmt.Sprintf("etype=%d", et)
|
||||
}
|
||||
|
||||
/*
|
||||
* sprint_depchain prints a dependency chain
|
||||
* of nodes into fmt.
|
||||
* It is used by typecheck in the case of OLITERAL nodes
|
||||
* to print constant definition loops.
|
||||
*/
|
||||
func sprint_depchain(fmt_ *string, stack *NodeList, cur *Node, first *Node) {
|
||||
for l := stack; l != nil; l = l.Next {
|
||||
if l.N.Op == cur.Op {
|
||||
if l.N != first {
|
||||
sprint_depchain(fmt_, l.Next, l.N, first)
|
||||
// sprint_depchain prints a dependency chain of nodes into fmt.
|
||||
// It is used by typecheck in the case of OLITERAL nodes
|
||||
// to print constant definition loops.
|
||||
func sprint_depchain(fmt_ *string, stack []*Node, cur *Node, first *Node) {
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
if n := stack[i]; n.Op == cur.Op {
|
||||
if n != first {
|
||||
sprint_depchain(fmt_, stack[:i], n, first)
|
||||
}
|
||||
*fmt_ += fmt.Sprintf("\n\t%v: %v uses %v", l.N.Line(), l.N, cur)
|
||||
*fmt_ += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cur)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* type check node *np.
|
||||
* replaces *np with a new pointer in some cases.
|
||||
* returns the final value of *np as a convenience.
|
||||
*/
|
||||
|
||||
var typecheck_tcstack *NodeList
|
||||
var typecheck_tcfree *NodeList
|
||||
var typecheck_tcstack []*Node
|
||||
|
||||
// typecheck type checks node *np.
|
||||
// It replaces *np with a new pointer in some cases.
|
||||
// It returns the final value of *np as a convenience.
|
||||
func typecheck(np **Node, top int) *Node {
|
||||
// cannot type check until all the source has been parsed
|
||||
if !typecheckok {
|
||||
@ -168,16 +161,15 @@ func typecheck(np **Node, top int) *Node {
|
||||
Yyerror("%v is not a type", n)
|
||||
break
|
||||
}
|
||||
|
||||
fmt_ = ""
|
||||
sprint_depchain(&fmt_, typecheck_tcstack, n, n)
|
||||
yyerrorl(int(n.Lineno), "constant definition loop%s", fmt_)
|
||||
}
|
||||
|
||||
if nsavederrors+nerrors == 0 {
|
||||
fmt_ = ""
|
||||
for l := typecheck_tcstack; l != nil; l = l.Next {
|
||||
fmt_ += fmt.Sprintf("\n\t%v %v", l.N.Line(), l.N)
|
||||
for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
|
||||
x := typecheck_tcstack[i]
|
||||
fmt_ += fmt.Sprintf("\n\t%v %v", x.Line(), x)
|
||||
}
|
||||
Yyerror("typechecking loop involving %v%s", n, fmt_)
|
||||
}
|
||||
@ -188,27 +180,15 @@ func typecheck(np **Node, top int) *Node {
|
||||
|
||||
n.Typecheck = 2
|
||||
|
||||
var l *NodeList
|
||||
if typecheck_tcfree != nil {
|
||||
l = typecheck_tcfree
|
||||
typecheck_tcfree = l.Next
|
||||
} else {
|
||||
l = new(NodeList)
|
||||
}
|
||||
l.Next = typecheck_tcstack
|
||||
l.N = n
|
||||
typecheck_tcstack = l
|
||||
|
||||
typecheck_tcstack = append(typecheck_tcstack, n)
|
||||
typecheck1(&n, top)
|
||||
*np = n
|
||||
|
||||
n.Typecheck = 1
|
||||
|
||||
if typecheck_tcstack != l {
|
||||
Fatalf("typecheck stack out of sync")
|
||||
}
|
||||
typecheck_tcstack = l.Next
|
||||
l.Next = typecheck_tcfree
|
||||
typecheck_tcfree = l
|
||||
last := len(typecheck_tcstack) - 1
|
||||
typecheck_tcstack[last] = nil
|
||||
typecheck_tcstack = typecheck_tcstack[:last]
|
||||
|
||||
lineno = int32(lno)
|
||||
return n
|
||||
|
14
test/typecheckloop.go
Normal file
14
test/typecheckloop.go
Normal file
@ -0,0 +1,14 @@
|
||||
// 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.
|
||||
|
||||
// Verify that constant definition loops are caught during
|
||||
// typechecking and that the errors print correctly.
|
||||
|
||||
package main
|
||||
|
||||
const A = 1 + B // ERROR "constant definition loop\n.*A uses B\n.*B uses C\n.*C uses A"
|
||||
const B = C - 1 // ERROR "constant definition loop\n.*B uses C\n.*C uses B"
|
||||
const C = A + B + 1
|
Loading…
Reference in New Issue
Block a user