From f134742f24f950bd3b7c563fc36cccda8fd85e81 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9my=20Oudompheng?= Date: Tue, 27 Nov 2012 21:37:38 +0100 Subject: [PATCH] cmd/5g, cmd/8g: fix internal error on 64-bit indices statically bounded Fixes #4448. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6855100 --- src/cmd/5g/cgen.c | 12 +++++++----- src/cmd/5g/gg.h | 2 +- src/cmd/5g/gsubr.c | 2 +- src/cmd/8g/cgen.c | 14 ++++++++------ test/fixedbugs/issue4448.go | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 test/fixedbugs/issue4448.go diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c index bd56728bf5..764a2803f5 100644 --- a/src/cmd/5g/cgen.c +++ b/src/cmd/5g/cgen.c @@ -521,7 +521,7 @@ ret: * returns Prog* to patch to panic call. */ Prog* -cgenindex(Node *n, Node *res) +cgenindex(Node *n, Node *res, int bounded) { Node tmp, lo, hi, zero, n1, n2; @@ -534,7 +534,7 @@ cgenindex(Node *n, Node *res) cgen(n, &tmp); split64(&tmp, &lo, &hi); gmove(&lo, res); - if(debug['B']) { + if(bounded) { splitclean(); return nil; } @@ -889,6 +889,7 @@ agenr(Node *n, Node *a, Node *res) Prog *p1, *p2; uint32 w; uint64 v; + int bounded; if(debug['g']) dump("agenr-n", n); @@ -915,13 +916,14 @@ agenr(Node *n, Node *a, Node *res) case OINDEX: p2 = nil; // to be patched to panicindex. w = n->type->width; + bounded = debug['B'] || n->bounded; if(nr->addable) { if(!isconst(nr, CTINT)) tempname(&tmp, types[TINT32]); if(!isconst(nl, CTSTR)) agenr(nl, &n3, res); if(!isconst(nr, CTINT)) { - p2 = cgenindex(nr, &tmp); + p2 = cgenindex(nr, &tmp, bounded); regalloc(&n1, tmp.type, N); gmove(&tmp, &n1); } @@ -929,7 +931,7 @@ agenr(Node *n, Node *a, Node *res) if(nl->addable) { if(!isconst(nr, CTINT)) { tempname(&tmp, types[TINT32]); - p2 = cgenindex(nr, &tmp); + p2 = cgenindex(nr, &tmp, bounded); regalloc(&n1, tmp.type, N); gmove(&tmp, &n1); } @@ -938,7 +940,7 @@ agenr(Node *n, Node *a, Node *res) } } else { tempname(&tmp, types[TINT32]); - p2 = cgenindex(nr, &tmp); + p2 = cgenindex(nr, &tmp, bounded); nr = &tmp; if(!isconst(nl, CTSTR)) agenr(nl, &n3, res); diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h index 370cf6e038..394ca4730b 100644 --- a/src/cmd/5g/gg.h +++ b/src/cmd/5g/gg.h @@ -88,7 +88,7 @@ void ginscall(Node*, int); * cgen */ void agen(Node*, Node*); -Prog* cgenindex(Node *, Node *); +Prog* cgenindex(Node *, Node *, int); void igen(Node*, Node*, Node*); void agenr(Node *n, Node *a, Node *res); vlong fieldoffset(Type*, Node*); diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index 916d2a7453..ed0e73b88d 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -1937,7 +1937,7 @@ oindex: t = types[TINT32]; regalloc(reg1, t, N); regalloc(&n3, types[TINT32], reg1); - p2 = cgenindex(r, &n3); + p2 = cgenindex(r, &n3, debug['B'] || n->bounded); gmove(&n3, reg1); regfree(&n3); diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c index 9716d0616b..935831d751 100644 --- a/src/cmd/8g/cgen.c +++ b/src/cmd/8g/cgen.c @@ -464,8 +464,8 @@ flt2: // binary * n is an array index, and might be any size; res width is <= 32-bit. * returns Prog* to patch to panic call. */ -Prog* -igenindex(Node *n, Node *res) +static Prog* +igenindex(Node *n, Node *res, int bounded) { Node tmp, lo, hi, zero; @@ -485,7 +485,7 @@ igenindex(Node *n, Node *res) split64(&tmp, &lo, &hi); tempname(res, types[TUINT32]); gmove(&lo, res); - if(debug['B']) { + if(bounded) { splitclean(); return nil; } @@ -508,6 +508,7 @@ agen(Node *n, Node *res) uint32 w; uint64 v; Prog *p1, *p2; + int bounded; if(debug['g']) { dump("\nagen-res", res); @@ -584,26 +585,27 @@ agen(Node *n, Node *res) case OINDEX: p2 = nil; // to be patched to panicindex. w = n->type->width; + bounded = debug['B'] || n->bounded; if(nr->addable) { // Generate &nl first, and move nr into register. if(!isconst(nl, CTSTR)) igen(nl, &n3, res); if(!isconst(nr, CTINT)) { - p2 = igenindex(nr, &tmp); + p2 = igenindex(nr, &tmp, bounded); regalloc(&n1, tmp.type, N); gmove(&tmp, &n1); } } else if(nl->addable) { // Generate nr first, and move &nl into register. if(!isconst(nr, CTINT)) { - p2 = igenindex(nr, &tmp); + p2 = igenindex(nr, &tmp, bounded); regalloc(&n1, tmp.type, N); gmove(&tmp, &n1); } if(!isconst(nl, CTSTR)) igen(nl, &n3, res); } else { - p2 = igenindex(nr, &tmp); + p2 = igenindex(nr, &tmp, bounded); nr = &tmp; if(!isconst(nl, CTSTR)) igen(nl, &n3, res); diff --git a/test/fixedbugs/issue4448.go b/test/fixedbugs/issue4448.go new file mode 100644 index 0000000000..fa1d9fe49d --- /dev/null +++ b/test/fixedbugs/issue4448.go @@ -0,0 +1,37 @@ +// run + +// Copyright 2012 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. + +// Issue 4448: 64-bit indices that are statically known +// to be bounded make 5g and 8g generate a dangling branch. + +package main + +const b26 uint64 = 0x022fdd63cc95386d + +var bitPos [64]int + +func init() { + for p := uint(0); p < 64; p++ { + bitPos[b26<

>58] = int(p) + } +} + +func MinPos(w uint64) int { + if w == 0 { + panic("bit: MinPos(0) undefined") + } + return bitPos[((w&-w)*b26)>>58] +} + +func main() { + const one = uint64(1) + for i := 0; i < 64; i++ { + if MinPos(1<