Commit e852202f authored by Russ Cox's avatar Russ Cox

gc: descriptive panic for nil pointer -> value method call

R=ken2
CC=golang-dev
https://golang.org/cl/4646042
parent f4c7db0e
...@@ -1525,6 +1525,7 @@ noreturn(Prog *p) ...@@ -1525,6 +1525,7 @@ noreturn(Prog *p)
symlist[1] = pkglookup("panicslice", runtimepkg); symlist[1] = pkglookup("panicslice", runtimepkg);
symlist[2] = pkglookup("throwinit", runtimepkg); symlist[2] = pkglookup("throwinit", runtimepkg);
symlist[3] = pkglookup("panic", runtimepkg); symlist[3] = pkglookup("panic", runtimepkg);
symlist[4] = pkglookup("panicwrap", runtimepkg);
} }
s = p->to.sym; s = p->to.sym;
......
...@@ -1677,6 +1677,7 @@ noreturn(Prog *p) ...@@ -1677,6 +1677,7 @@ noreturn(Prog *p)
symlist[1] = pkglookup("panicslice", runtimepkg); symlist[1] = pkglookup("panicslice", runtimepkg);
symlist[2] = pkglookup("throwinit", runtimepkg); symlist[2] = pkglookup("throwinit", runtimepkg);
symlist[3] = pkglookup("panic", runtimepkg); symlist[3] = pkglookup("panic", runtimepkg);
symlist[4] = pkglookup("panicwrap", runtimepkg);
} }
s = p->to.sym; s = p->to.sym;
......
...@@ -1533,6 +1533,7 @@ noreturn(Prog *p) ...@@ -1533,6 +1533,7 @@ noreturn(Prog *p)
symlist[1] = pkglookup("panicslice", runtimepkg); symlist[1] = pkglookup("panicslice", runtimepkg);
symlist[2] = pkglookup("throwinit", runtimepkg); symlist[2] = pkglookup("throwinit", runtimepkg);
symlist[3] = pkglookup("panic", runtimepkg); symlist[3] = pkglookup("panic", runtimepkg);
symlist[4] = pkglookup("panicwrap", runtimepkg);
} }
s = p->to.sym; s = p->to.sym;
......
...@@ -6,6 +6,7 @@ char *runtimeimport = ...@@ -6,6 +6,7 @@ char *runtimeimport =
"func \"\".panicslice ()\n" "func \"\".panicslice ()\n"
"func \"\".throwreturn ()\n" "func \"\".throwreturn ()\n"
"func \"\".throwinit ()\n" "func \"\".throwinit ()\n"
"func \"\".panicwrap (? string, ? string, ? string)\n"
"func \"\".panic (? interface { })\n" "func \"\".panic (? interface { })\n"
"func \"\".recover (? *int32) interface { }\n" "func \"\".recover (? *int32) interface { }\n"
"func \"\".printbool (? bool)\n" "func \"\".printbool (? bool)\n"
...@@ -22,6 +23,7 @@ char *runtimeimport = ...@@ -22,6 +23,7 @@ char *runtimeimport =
"func \"\".printsp ()\n" "func \"\".printsp ()\n"
"func \"\".goprintf ()\n" "func \"\".goprintf ()\n"
"func \"\".concatstring ()\n" "func \"\".concatstring ()\n"
"func \"\".append ()\n"
"func \"\".appendslice (typ *uint8, x any, y []any) any\n" "func \"\".appendslice (typ *uint8, x any, y []any) any\n"
"func \"\".cmpstring (? string, ? string) int\n" "func \"\".cmpstring (? string, ? string) int\n"
"func \"\".slicestring (? string, ? int, ? int) string\n" "func \"\".slicestring (? string, ? int, ? int) string\n"
...@@ -81,7 +83,7 @@ char *runtimeimport = ...@@ -81,7 +83,7 @@ char *runtimeimport =
"func \"\".selectgo (sel *uint8)\n" "func \"\".selectgo (sel *uint8)\n"
"func \"\".block ()\n" "func \"\".block ()\n"
"func \"\".makeslice (typ *uint8, nel int64, cap int64) []any\n" "func \"\".makeslice (typ *uint8, nel int64, cap int64) []any\n"
"func \"\".growslice (typ *uint8, old []any, cap int64) []any\n" "func \"\".growslice (typ *uint8, old []any, n int64) []any\n"
"func \"\".sliceslice1 (old []any, lb uint64, width uint64) []any\n" "func \"\".sliceslice1 (old []any, lb uint64, width uint64) []any\n"
"func \"\".sliceslice (old []any, lb uint64, hb uint64, width uint64) []any\n" "func \"\".sliceslice (old []any, lb uint64, hb uint64, width uint64) []any\n"
"func \"\".slicearray (old *any, nel uint64, lb uint64, hb uint64, width uint64) []any\n" "func \"\".slicearray (old *any, nel uint64, lb uint64, hb uint64, width uint64) []any\n"
......
...@@ -15,6 +15,7 @@ func panicindex() ...@@ -15,6 +15,7 @@ func panicindex()
func panicslice() func panicslice()
func throwreturn() func throwreturn()
func throwinit() func throwinit()
func panicwrap(string, string, string)
func panic(interface{}) func panic(interface{})
func recover(*int32) interface{} func recover(*int32) interface{}
......
...@@ -3131,8 +3131,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) ...@@ -3131,8 +3131,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
NodeList *l, *args, *in, *out; NodeList *l, *args, *in, *out;
Type *tpad; Type *tpad;
int isddd; int isddd;
Val v;
if(0 && debug['r']) if(debug['r'])
print("genwrapper rcvrtype=%T method=%T newnam=%S\n", print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
rcvr, method, newnam); rcvr, method, newnam);
...@@ -3174,17 +3175,38 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) ...@@ -3174,17 +3175,38 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
args = list(args, l->n->left); args = list(args, l->n->left);
isddd = l->n->left->isddd; isddd = l->n->left->isddd;
} }
// generate nil pointer check for better error
if(isptr[rcvr->etype] && rcvr->type == getthisx(method->type)->type->type) {
// generating wrapper from *T to T.
n = nod(OIF, N, N);
n->ntest = nod(OEQ, this->left, nodnil());
// these strings are already in the reflect tables,
// so no space cost to use them here.
l = nil;
v.ctype = CTSTR;
v.u.sval = strlit(rcvr->type->sym->pkg->name); // package name
l = list(l, nodlit(v));
v.u.sval = strlit(rcvr->type->sym->name); // type name
l = list(l, nodlit(v));
v.u.sval = strlit(method->sym->name);
l = list(l, nodlit(v)); // method name
call = nod(OCALL, syslook("panicwrap", 0), N);
call->list = l;
n->nbody = list1(call);
fn->nbody = list(fn->nbody, n);
}
// generate call // generate call
call = nod(OCALL, adddot(nod(OXDOT, this->left, newname(method->sym))), N); call = nod(OCALL, adddot(nod(OXDOT, this->left, newname(method->sym))), N);
call->list = args; call->list = args;
call->isddd = isddd; call->isddd = isddd;
fn->nbody = list1(call);
if(method->type->outtuple > 0) { if(method->type->outtuple > 0) {
n = nod(ORETURN, N, N); n = nod(ORETURN, N, N);
n->list = fn->nbody; n->list = list1(call);
fn->nbody = list1(n); call = n;
} }
fn->nbody = list(fn->nbody, call);
if(0 && debug['r']) if(0 && debug['r'])
dumplist("genwrapper body", fn->nbody); dumplist("genwrapper body", fn->nbody);
......
...@@ -131,3 +131,8 @@ func printany(i interface{}) { ...@@ -131,3 +131,8 @@ func printany(i interface{}) {
print("(", typestring(i), ") ", i) print("(", typestring(i), ") ", i)
} }
} }
// called from generated code
func panicwrap(pkg, typ, meth string) {
panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
}
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