Commit 23e62d16 authored by Russ Cox's avatar Russ Cox

stricter interface conversion rule: i.(T)

must have non-nil i.

R=ken
OCL=29136
CL=29136
parent 140aed9a
...@@ -32,6 +32,7 @@ char *sysimport = ...@@ -32,6 +32,7 @@ char *sysimport =
"func sys.ifaceI2T (sigt *uint8, iface any) (ret any)\n" "func sys.ifaceI2T (sigt *uint8, iface any) (ret any)\n"
"func sys.ifaceI2T2 (sigt *uint8, iface any) (ret any, ok bool)\n" "func sys.ifaceI2T2 (sigt *uint8, iface any) (ret any, ok bool)\n"
"func sys.ifaceI2I (sigi *uint8, iface any) (ret any)\n" "func sys.ifaceI2I (sigi *uint8, iface any) (ret any)\n"
"func sys.ifaceI2Ix (sigi *uint8, iface any) (ret any)\n"
"func sys.ifaceI2I2 (sigi *uint8, iface any) (ret any, ok bool)\n" "func sys.ifaceI2I2 (sigi *uint8, iface any) (ret any, ok bool)\n"
"func sys.ifaceeq (i1 any, i2 any) (ret bool)\n" "func sys.ifaceeq (i1 any, i2 any) (ret bool)\n"
"func sys.efaceeq (i1 any, i2 any) (ret bool)\n" "func sys.efaceeq (i1 any, i2 any) (ret bool)\n"
......
...@@ -42,6 +42,7 @@ func ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any); ...@@ -42,6 +42,7 @@ func ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any);
func ifaceI2T(sigt *byte, iface any) (ret any); func ifaceI2T(sigt *byte, iface any) (ret any);
func ifaceI2T2(sigt *byte, iface any) (ret any, ok bool); func ifaceI2T2(sigt *byte, iface any) (ret any, ok bool);
func ifaceI2I(sigi *byte, iface any) (ret any); func ifaceI2I(sigi *byte, iface any) (ret any);
func ifaceI2Ix(sigi *byte, iface any) (ret any);
func ifaceI2I2(sigi *byte, iface any) (ret any, ok bool); func ifaceI2I2(sigi *byte, iface any) (ret any, ok bool);
func ifaceeq(i1 any, i2 any) (ret bool); func ifaceeq(i1 any, i2 any) (ret bool);
func efaceeq(i1 any, i2 any) (ret bool); func efaceeq(i1 any, i2 any) (ret bool);
......
...@@ -12,6 +12,7 @@ enum ...@@ -12,6 +12,7 @@ enum
I2T, I2T,
I2T2, I2T2,
I2I, I2I,
I2Ix,
I2I2, I2I2,
T2I, T2I,
I2Isame, I2Isame,
...@@ -524,7 +525,7 @@ loop: ...@@ -524,7 +525,7 @@ loop:
case I2T: case I2T:
et = I2T2; et = I2T2;
break; break;
case I2I: case I2Ix:
et = I2I2; et = I2I2;
break; break;
case E2I: case E2I:
...@@ -2947,6 +2948,8 @@ ifaceas1(Type *dst, Type *src, int explicit) ...@@ -2947,6 +2948,8 @@ ifaceas1(Type *dst, Type *src, int explicit)
ifacecheck(dst, src, lineno, explicit); ifacecheck(dst, src, lineno, explicit);
if(isnilinter(src)) if(isnilinter(src))
return E2I; return E2I;
if(explicit)
return I2Ix;
return I2I; return I2I;
} }
if(isnilinter(dst)) if(isnilinter(dst))
...@@ -2983,6 +2986,7 @@ ifacename[] = ...@@ -2983,6 +2986,7 @@ ifacename[] =
[I2T] = "ifaceI2T", [I2T] = "ifaceI2T",
[I2T2] = "ifaceI2T2", [I2T2] = "ifaceI2T2",
[I2I] = "ifaceI2I", [I2I] = "ifaceI2I",
[I2Ix] = "ifaceI2Ix",
[I2I2] = "ifaceI2I2", [I2I2] = "ifaceI2I2",
[I2Isame] = "ifaceI2Isame", [I2Isame] = "ifaceI2Isame",
[E2T] = "ifaceE2T", [E2T] = "ifaceE2T",
...@@ -3038,6 +3042,7 @@ ifacecvt(Type *tl, Node *n, int et) ...@@ -3038,6 +3042,7 @@ ifacecvt(Type *tl, Node *n, int et)
case I2T: case I2T:
case I2T2: case I2T2:
case I2I: case I2I:
case I2Ix:
case I2I2: case I2I2:
case E2T: case E2T:
case E2T2: case E2T2:
......
...@@ -431,6 +431,7 @@ sys·ifaceI2E(Iface i, Eface ret) ...@@ -431,6 +431,7 @@ sys·ifaceI2E(Iface i, Eface ret)
} }
// ifaceI2I(sigi *byte, iface any) (ret any); // ifaceI2I(sigi *byte, iface any) (ret any);
// called only for implicit (no type assertion) conversions
void void
sys·ifaceI2I(Sigi *si, Iface i, Iface ret) sys·ifaceI2I(Sigi *si, Iface i, Iface ret)
{ {
...@@ -438,7 +439,6 @@ sys·ifaceI2I(Sigi *si, Iface i, Iface ret) ...@@ -438,7 +439,6 @@ sys·ifaceI2I(Sigi *si, Iface i, Iface ret)
im = i.type; im = i.type;
if(im == nil) { if(im == nil) {
//TODO(rsc): fixme
// If incoming interface is uninitialized (zeroed) // If incoming interface is uninitialized (zeroed)
// make the outgoing interface zeroed as well. // make the outgoing interface zeroed as well.
ret = niliface; ret = niliface;
...@@ -451,6 +451,27 @@ sys·ifaceI2I(Sigi *si, Iface i, Iface ret) ...@@ -451,6 +451,27 @@ sys·ifaceI2I(Sigi *si, Iface i, Iface ret)
FLUSH(&ret); FLUSH(&ret);
} }
// ifaceI2Ix(sigi *byte, iface any) (ret any);
// called only for explicit conversions (with type assertion).
void
sys·ifaceI2Ix(Sigi *si, Iface i, Iface ret)
{
Itype *im;
im = i.type;
if(im == nil) {
// explicit conversions require non-nil interface value.
printf("interface is nil, not %s\n", si->name);
throw("interface conversion");
} else {
ret = i;
if(im->sigi != si)
ret.type = itype(si, im->sigt, 0);
}
FLUSH(&ret);
}
// ifaceI2I2(sigi *byte, iface any) (ret any, ok bool); // ifaceI2I2(sigi *byte, iface any) (ret any, ok bool);
void void
sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok) sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok)
...@@ -458,14 +479,13 @@ sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok) ...@@ -458,14 +479,13 @@ sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok)
Itype *im; Itype *im;
im = i.type; im = i.type;
ok = true;
if(im == nil) { if(im == nil) {
//TODO: fixme // If incoming interface is nil, the conversion fails.
// If incoming interface is uninitialized (zeroed)
// make the outgoing interface zeroed as well.
ret = niliface; ret = niliface;
ok = false;
} else { } else {
ret = i; ret = i;
ok = true;
if(im->sigi != si) { if(im->sigi != si) {
ret.type = itype(si, im->sigt, 1); ret.type = itype(si, im->sigt, 1);
if(ret.type == nil) { if(ret.type == nil) {
...@@ -480,6 +500,7 @@ sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok) ...@@ -480,6 +500,7 @@ sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok)
} }
// ifaceE2I(sigi *byte, iface any) (ret any); // ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
void void
sys·ifaceE2I(Sigi *si, Eface e, Iface ret) sys·ifaceE2I(Sigi *si, Eface e, Iface ret)
{ {
...@@ -487,8 +508,9 @@ sys·ifaceE2I(Sigi *si, Eface e, Iface ret) ...@@ -487,8 +508,9 @@ sys·ifaceE2I(Sigi *si, Eface e, Iface ret)
t = e.type; t = e.type;
if(t == nil) { if(t == nil) {
//TODO(rsc): fixme // explicit conversions require non-nil interface value.
ret = niliface; printf("interface is nil, not %s\n", si->name);
throw("interface conversion");
} else { } else {
ret.data = e.data; ret.data = e.data;
ret.type = itype(si, t, 0); ret.type = itype(si, t, 0);
...@@ -505,8 +527,9 @@ sys·ifaceE2I2(Sigi *si, Eface e, Iface ret, bool ok) ...@@ -505,8 +527,9 @@ sys·ifaceE2I2(Sigi *si, Eface e, Iface ret, bool ok)
t = e.type; t = e.type;
ok = true; ok = true;
if(t == nil) { if(t == nil) {
//TODO(rsc): fixme // If incoming interface is nil, the conversion fails.
ret = niliface; ret = niliface;
ok = false;
} else { } else {
ret.data = e.data; ret.data = e.data;
ret.type = itype(si, t, 1); ret.type = itype(si, t, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment