]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix constant pointer comparison failure
authorMatthew Dempsky <mdempsky@google.com>
Sat, 7 Apr 2018 10:08:46 +0000 (03:08 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 9 Apr 2018 23:19:45 +0000 (23:19 +0000)
Previously, constant pointer-typed expressions could use either Mpint
or NilVal as their Val depending on their construction, but const.go
expects each type to have a single corresponding Val kind.

This CL changes pointer-typed expressions to exclusively use Mpint.

Fixes #21221.

Change-Id: I6ba36c9b11eb19a68306f0b296acb11a8c254c41
Reviewed-on: https://go-review.googlesource.com/105315
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/const.go
src/cmd/compile/internal/gc/export.go
test/const1.go
test/fixedbugs/issue21221.go [new file with mode: 0644]

index 0e00fa070a1ddd5780771a42852ccb37483a7d8e..ca0f523a791fb76aa4d4388373f5f56e17f75ea3 100644 (file)
@@ -319,7 +319,8 @@ func (p *importer) pkg() *types.Pkg {
 }
 
 func idealType(typ *types.Type) *types.Type {
-       if typ.IsUntyped() {
+       switch typ {
+       case types.Idealint, types.Idealrune, types.Idealfloat, types.Idealcomplex:
                // canonicalize ideal types
                typ = types.Types[TIDEAL]
        }
@@ -795,8 +796,12 @@ func (p *importer) value(typ *types.Type) (x Val) {
        case floatTag:
                f := newMpflt()
                p.float(f)
-               if typ == types.Idealint || typ.IsInteger() {
+               if typ == types.Idealint || typ.IsInteger() || typ.IsPtr() || typ.IsUnsafePtr() {
                        // uncommon case: large int encoded as float
+                       //
+                       // This happens for unsigned typed integers
+                       // and (on 64-bit platforms) pointers because
+                       // of values in the range [2^63, 2^64).
                        u := new(Mpint)
                        u.SetFloat(f)
                        x.U = u
@@ -929,18 +934,7 @@ func (p *importer) node() *Node {
                pos := p.pos()
                typ := p.typ()
                n := npos(pos, nodlit(p.value(typ)))
-               if !typ.IsUntyped() {
-                       // Type-checking simplifies unsafe.Pointer(uintptr(c))
-                       // to unsafe.Pointer(c) which then cannot type-checked
-                       // again. Re-introduce explicit uintptr(c) conversion.
-                       // (issue 16317).
-                       if typ.IsUnsafePtr() {
-                               n = nodl(pos, OCONV, n, nil)
-                               n.Type = types.Types[TUINTPTR]
-                       }
-                       n = nodl(pos, OCONV, n, nil)
-                       n.Type = typ
-               }
+               n.Type = idealType(typ)
                return n
 
        case ONAME:
index e4bbfe876df762e5f628dd250f9c9cb06205484b..27c2e14d767d24c6a4ba998ea201e79af13ca095 100644 (file)
@@ -331,26 +331,11 @@ func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
                case TARRAY:
                        goto bad
 
-               case TPTR32,
-                       TPTR64,
-                       TINTER,
-                       TMAP,
-                       TCHAN,
-                       TFUNC,
-                       TSLICE,
-                       TUNSAFEPTR:
-                       break
+               case TPTR32, TPTR64, TUNSAFEPTR:
+                       n.SetVal(Val{new(Mpint)})
 
-               // A nil literal may be converted to uintptr
-               // if it is an unsafe.Pointer
-               case TUINTPTR:
-                       if n.Type.Etype == TUNSAFEPTR {
-                               i := new(Mpint)
-                               i.SetInt64(0)
-                               n.SetVal(Val{i})
-                       } else {
-                               goto bad
-                       }
+               case TCHAN, TFUNC, TINTER, TMAP, TSLICE:
+                       break
                }
 
        case CTSTR, CTBOOL:
index a5837286085f993d46f0388b8cd28d4fa547d8eb..f0fdc5bd257a653ed58bc6bb624b0861469d1102 100644 (file)
@@ -145,7 +145,7 @@ func importconst(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type, val
        }
 
        n := npos(pos, nodlit(val))
-       n = convlit1(n, t, false, reuseOK)
+       n.Type = t
        n.Sym = s
        declare(n, PEXTERN)
 
index 58bddee7e072d3e6b4bb147c14e831b56a889af1..62abe4145ad1fa7a6fa6daa2dab76734bc033e25 100644 (file)
@@ -90,5 +90,5 @@ func main() {
 const ptr = nil // ERROR "const.*nil"
 const _ = string([]byte(nil)) // ERROR "is not a? ?constant"
 const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a? ?constant"
-const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type"
-const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type"
+const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type|is not a constant"
+const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type|is not a constant"
diff --git a/test/fixedbugs/issue21221.go b/test/fixedbugs/issue21221.go
new file mode 100644 (file)
index 0000000..bd5a4b5
--- /dev/null
@@ -0,0 +1,18 @@
+// run
+
+// Copyright 2018 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 "unsafe"
+
+func main() {
+       if unsafe.Pointer(uintptr(0)) != unsafe.Pointer(nil) {
+               panic("fail")
+       }
+       if (*int)(unsafe.Pointer(uintptr(0))) != (*int)(nil) {
+               panic("fail")
+       }
+}