while(n->op == OCONVNOP)
n = n->left;
+ if(isconst(n, CTNIL) && n->type->width > widthptr) {
+ // Use of a nil interface or nil slice.
+ // Create a temporary we can take the address of and read.
+ // The generated code is just going to panic, so it need not
+ // be terribly efficient. See issue 3670.
+ tempname(&n1, n->type);
+ clearfat(&n1);
+ regalloc(&n2, types[tptr], res);
+ gins(ALEAQ, &n1, &n2);
+ gmove(&n2, res);
+ regfree(&n2);
+ goto ret;
+ }
+
+
if(n->addable) {
memset(&n1, 0, sizeof n1);
n1.op = OADDR;
while(n->op == OCONVNOP)
n = n->left;
+ if(isconst(n, CTNIL) && n->type->width > widthptr) {
+ // Use of a nil interface or nil slice.
+ // Create a temporary we can take the address of and read.
+ // The generated code is just going to panic, so it need not
+ // be terribly efficient. See issue 3670.
+ tempname(&n1, n->type);
+ clearfat(&n1);
+ regalloc(&n2, types[tptr], res);
+ gins(ALEAQ, &n1, &n2);
+ gmove(&n2, res);
+ regfree(&n2);
+ goto ret;
+ }
+
if(n->addable) {
regalloc(&n1, types[tptr], res);
gins(ALEAQ, n, &n1);
case AMOVSD:
if(f != N && t != N && samaddr(f, t))
return nil;
+ break;
+
+ case ALEAQ:
+ if(f != N && isconst(f, CTNIL)) {
+ fatal("gins LEAQ nil %T", f->type);
+ }
+ break;
}
memset(&af, 0, sizeof af);
while(n->op == OCONVNOP)
n = n->left;
+ if(isconst(n, CTNIL) && n->type->width > widthptr) {
+ // Use of a nil interface or nil slice.
+ // Create a temporary we can take the address of and read.
+ // The generated code is just going to panic, so it need not
+ // be terribly efficient. See issue 3670.
+ tempname(&n1, n->type);
+ clearfat(&n1);
+ regalloc(&n2, types[tptr], res);
+ gins(ALEAL, &n1, &n2);
+ gmove(&n2, res);
+ regfree(&n2);
+ return;
+ }
+
// addressable var is easy
if(n->addable) {
if(n->op == OREGISTER)
case AMOVL:
if(f != N && t != N && samaddr(f, t))
return nil;
+ break;
+
+ case ALEAL:
+ if(f != N && isconst(f, CTNIL))
+ fatal("gins LEAQ nil %T", f->type);
+ break;
}
memset(&af, 0, sizeof af);
// The no-op conversion here used to confuse the compiler
// into doing a load-effective-address of nil.
+// See issue 3670.
package main
type T interface {}
+var x bool
+
func main() {
reflect.TypeOf(nil)
- reflect.TypeOf(T(nil)) // used to fail
+ reflect.TypeOf(T(nil)) // used to miscompile
+ shouldPanic()
+}
+
+func f() byte {
+ return []byte(nil)[0] // used to miscompile
+}
+
+func shouldPanic() {
+ defer func() {
+ if recover() == nil {
+ panic("not panicking")
+ }
+ }()
+ f()
}