}
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]
}
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
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:
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:
}
n := npos(pos, nodlit(val))
- n = convlit1(n, t, false, reuseOK)
+ n.Type = t
n.Sym = s
declare(n, PEXTERN)
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"
--- /dev/null
+// 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")
+ }
+}