go.tools/go/types: fix unsafe.Pointer conversions
Make compliant with gc. Spec is not very clear. Also: Fix error handling (don't destroy x before using it in error message). Fixes golang/go#6326. R=adonovan CC=golang-dev https://golang.org/cl/13632043
This commit is contained in:
parent
932a87ce16
commit
6688b01dc1
|
|
@ -11,12 +11,13 @@ import "code.google.com/p/go.tools/go/exact"
|
||||||
// Conversion type-checks the conversion T(x).
|
// Conversion type-checks the conversion T(x).
|
||||||
// The result is in x.
|
// The result is in x.
|
||||||
func (check *checker) conversion(x *operand, T Type) {
|
func (check *checker) conversion(x *operand, T Type) {
|
||||||
|
var ok bool
|
||||||
switch {
|
switch {
|
||||||
case x.mode == constant && isConstType(T):
|
case x.mode == constant && isConstType(T):
|
||||||
// constant conversion
|
// constant conversion
|
||||||
switch t := T.Underlying().(*Basic); {
|
switch t := T.Underlying().(*Basic); {
|
||||||
case isRepresentableConst(x.val, check.conf, t.kind, &x.val):
|
case isRepresentableConst(x.val, check.conf, t.kind, &x.val):
|
||||||
// nothing to do
|
ok = true
|
||||||
case x.isInteger() && isString(t):
|
case x.isInteger() && isString(t):
|
||||||
codepoint := int64(-1)
|
codepoint := int64(-1)
|
||||||
if i, ok := exact.Int64Val(x.val); ok {
|
if i, ok := exact.Int64Val(x.val); ok {
|
||||||
|
|
@ -26,18 +27,17 @@ func (check *checker) conversion(x *operand, T Type) {
|
||||||
// conversion. This is the same as converting any other out-of-range
|
// conversion. This is the same as converting any other out-of-range
|
||||||
// value - let string(codepoint) do the work.
|
// value - let string(codepoint) do the work.
|
||||||
x.val = exact.MakeString(string(codepoint))
|
x.val = exact.MakeString(string(codepoint))
|
||||||
default:
|
ok = true
|
||||||
x.mode = invalid
|
|
||||||
}
|
}
|
||||||
case x.isConvertible(check.conf, T):
|
case x.isConvertible(check.conf, T):
|
||||||
// non-constant conversion
|
// non-constant conversion
|
||||||
x.mode = value
|
x.mode = value
|
||||||
default:
|
ok = true
|
||||||
x.mode = invalid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.mode == invalid {
|
if !ok {
|
||||||
check.errorf(x.pos(), "cannot convert %s to %s", x, T)
|
check.errorf(x.pos(), "cannot convert %s to %s", x, T)
|
||||||
|
x.mode = invalid
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,17 +116,20 @@ func (x *operand) isConvertible(conf *Config, T Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isUintptr(typ Type) bool {
|
func isUintptr(typ Type) bool {
|
||||||
t, ok := typ.(*Basic)
|
t, ok := typ.Underlying().(*Basic)
|
||||||
return ok && t.kind == Uintptr
|
return ok && t.kind == Uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
func isUnsafePointer(typ Type) bool {
|
func isUnsafePointer(typ Type) bool {
|
||||||
t, ok := typ.(*Basic)
|
// TODO(gri): Is this (typ.Underlying() instead of just typ) correct?
|
||||||
|
// The spec does't say so, but gc claims it is. See also
|
||||||
|
// issue 6326.
|
||||||
|
t, ok := typ.Underlying().(*Basic)
|
||||||
return ok && t.kind == UnsafePointer
|
return ok && t.kind == UnsafePointer
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPointer(typ Type) bool {
|
func isPointer(typ Type) bool {
|
||||||
_, ok := typ.(*Pointer)
|
_, ok := typ.Underlying().(*Pointer)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
package conversions
|
package conversions
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
// argument count
|
// argument count
|
||||||
var (
|
var (
|
||||||
_ = int() /* ERROR "missing argument" */
|
_ = int() /* ERROR "missing argument" */
|
||||||
|
|
@ -77,4 +79,10 @@ func interface_conversions() {
|
||||||
_ = I3(i3)
|
_ = I3(i3)
|
||||||
|
|
||||||
// TODO(gri) add more tests, improve error message
|
// TODO(gri) add more tests, improve error message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func issue6326() {
|
||||||
|
type T unsafe.Pointer
|
||||||
|
var x T
|
||||||
|
_ = uintptr(x) // see issue 6326
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue