mirror of
https://github.com/golang/go
synced 2024-11-18 17:14:45 -07:00
cmd/internal/gc: Toughen escape analysis against some bugs.
Ensures that parameter flow bits are not set for tags EscScope, EscHeap, EscNever; crash the compiler earl to expose faulty logic, rather than flake out silently downstream. Change-Id: I1428129980ae047d02975f033d56cbbd04f49579 Reviewed-on: https://go-review.googlesource.com/9601 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
7bebccb972
commit
bc44b818a6
@ -343,12 +343,11 @@ const (
|
|||||||
// escMax returns the maximum of an existing escape value
|
// escMax returns the maximum of an existing escape value
|
||||||
// (and its additional parameter flow flags) and a new escape type.
|
// (and its additional parameter flow flags) and a new escape type.
|
||||||
func escMax(e, etype uint16) uint16 {
|
func escMax(e, etype uint16) uint16 {
|
||||||
if e&EscMask == EscHeap {
|
if e&EscMask >= EscScope {
|
||||||
// normalize
|
// normalize
|
||||||
if e != EscHeap {
|
if e&^EscMask != 0 {
|
||||||
Fatal("Escape information had tag bits combined with 'EscHeap' ")
|
Fatal("Escape information had unexpected return encoding bits (w/ EscScope, EscHeap, EscNever), e&EscMask=%v", e&EscMask)
|
||||||
}
|
}
|
||||||
return EscHeap
|
|
||||||
}
|
}
|
||||||
if e&EscMask > etype {
|
if e&EscMask > etype {
|
||||||
return e
|
return e
|
||||||
@ -1563,7 +1562,7 @@ func escwalk(e *EscState, level Level, dst *Node, src *Node) {
|
|||||||
|
|
||||||
// Input parameter flowing to output parameter?
|
// Input parameter flowing to output parameter?
|
||||||
var leaks bool
|
var leaks bool
|
||||||
if funcOutputAndInput(dst, src) && src.Esc&EscMask != EscScope && src.Esc != EscHeap && dst.Esc != EscHeap {
|
if funcOutputAndInput(dst, src) && src.Esc&EscMask < EscScope && dst.Esc != EscHeap {
|
||||||
// This case handles:
|
// This case handles:
|
||||||
// 1. return in
|
// 1. return in
|
||||||
// 2. return &in
|
// 2. return &in
|
||||||
@ -1586,7 +1585,7 @@ func escwalk(e *EscState, level Level, dst *Node, src *Node) {
|
|||||||
// If parameter content escapes to heap, set EscContentEscapes
|
// If parameter content escapes to heap, set EscContentEscapes
|
||||||
// Note minor confusion around escape from pointer-to-struct vs escape from struct
|
// Note minor confusion around escape from pointer-to-struct vs escape from struct
|
||||||
if dst.Esc == EscHeap &&
|
if dst.Esc == EscHeap &&
|
||||||
src.Op == ONAME && src.Class == PPARAM && src.Esc != EscHeap &&
|
src.Op == ONAME && src.Class == PPARAM && src.Esc&EscMask < EscScope &&
|
||||||
level.int() > 0 {
|
level.int() > 0 {
|
||||||
src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
|
src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
|
||||||
if Debug['m'] != 0 {
|
if Debug['m'] != 0 {
|
||||||
@ -1598,7 +1597,7 @@ func escwalk(e *EscState, level Level, dst *Node, src *Node) {
|
|||||||
|
|
||||||
switch src.Op {
|
switch src.Op {
|
||||||
case ONAME:
|
case ONAME:
|
||||||
if src.Class == PPARAM && (leaks || dst.Escloopdepth < 0) && src.Esc != EscHeap {
|
if src.Class == PPARAM && (leaks || dst.Escloopdepth < 0) && src.Esc&EscMask < EscScope {
|
||||||
if level.guaranteedDereference() > 0 {
|
if level.guaranteedDereference() > 0 {
|
||||||
src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
|
src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
|
||||||
if Debug['m'] != 0 {
|
if Debug['m'] != 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user