]> Cypherpunks repositories - gostls13.git/commitdiff
gc: descriptive panic for nil pointer -> value method call
authorRuss Cox <rsc@golang.org>
Fri, 17 Jun 2011 19:23:27 +0000 (15:23 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 17 Jun 2011 19:23:27 +0000 (15:23 -0400)
R=ken2
CC=golang-dev
https://golang.org/cl/4646042

src/cmd/5g/reg.c
src/cmd/6g/reg.c
src/cmd/8g/reg.c
src/cmd/gc/builtin.c.boot
src/cmd/gc/runtime.go
src/cmd/gc/subr.c
src/pkg/runtime/error.go

index 5fba02c9e0cb0e482138b2adfe811efecda105cf..a4c61e4808098aec41577ce89a881b4f9c2fc27c 100644 (file)
@@ -1525,6 +1525,7 @@ noreturn(Prog *p)
                symlist[1] = pkglookup("panicslice", runtimepkg);
                symlist[2] = pkglookup("throwinit", runtimepkg);
                symlist[3] = pkglookup("panic", runtimepkg);
+               symlist[4] = pkglookup("panicwrap", runtimepkg);
        }
 
        s = p->to.sym;
index af9b29cbcdb251d14f9749a1943d98723c37b748..4d426304712bba082cb98f714c2b4fdeee8c2481 100644 (file)
@@ -1677,6 +1677,7 @@ noreturn(Prog *p)
                symlist[1] = pkglookup("panicslice", runtimepkg);
                symlist[2] = pkglookup("throwinit", runtimepkg);
                symlist[3] = pkglookup("panic", runtimepkg);
+               symlist[4] = pkglookup("panicwrap", runtimepkg);
        }
 
        s = p->to.sym;
index a2f3def3730896ef3ad4cc1cb78a97f346eb62ab..a4828c3a39c7b63043775e595ae5e825f473e258 100644 (file)
@@ -1533,6 +1533,7 @@ noreturn(Prog *p)
                symlist[1] = pkglookup("panicslice", runtimepkg);
                symlist[2] = pkglookup("throwinit", runtimepkg);
                symlist[3] = pkglookup("panic", runtimepkg);
+               symlist[4] = pkglookup("panicwrap", runtimepkg);
        }
 
        s = p->to.sym;
index c9bf501d1bcbea460e1f862248599901a6c36971..7659ac5bb3d726ad60171e61a3c89e0ed1e26e79 100644 (file)
@@ -6,6 +6,7 @@ char *runtimeimport =
        "func \"\".panicslice ()\n"
        "func \"\".throwreturn ()\n"
        "func \"\".throwinit ()\n"
+       "func \"\".panicwrap (? string, ? string, ? string)\n"
        "func \"\".panic (? interface { })\n"
        "func \"\".recover (? *int32) interface { }\n"
        "func \"\".printbool (? bool)\n"
@@ -22,6 +23,7 @@ char *runtimeimport =
        "func \"\".printsp ()\n"
        "func \"\".goprintf ()\n"
        "func \"\".concatstring ()\n"
+       "func \"\".append ()\n"
        "func \"\".appendslice (typ *uint8, x any, y []any) any\n"
        "func \"\".cmpstring (? string, ? string) int\n"
        "func \"\".slicestring (? string, ? int, ? int) string\n"
@@ -81,7 +83,7 @@ char *runtimeimport =
        "func \"\".selectgo (sel *uint8)\n"
        "func \"\".block ()\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 \"\".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"
index 00fc720b868ef3b9983a7d6812158b765f1fd5a4..e13c95db93a90fdf327e07d2bba1eca4784f9b1a 100644 (file)
@@ -15,6 +15,7 @@ func panicindex()
 func panicslice()
 func throwreturn()
 func throwinit()
+func panicwrap(string, string, string)
 
 func panic(interface{})
 func recover(*int32) interface{}
index 49797f9df6755ec7bea2d00b967113d0a2cb4276..8eb60de319f9f9c8035e1cefd070110487e9977d 100644 (file)
@@ -3131,8 +3131,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
        NodeList *l, *args, *in, *out;
        Type *tpad;
        int isddd;
+       Val v;
 
-       if(0 && debug['r'])
+       if(debug['r'])
                print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
                        rcvr, method, newnam);
 
@@ -3174,17 +3175,38 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
                args = list(args, l->n->left);
                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
        call = nod(OCALL, adddot(nod(OXDOT, this->left, newname(method->sym))), N);
        call->list = args;
        call->isddd = isddd;
-       fn->nbody = list1(call);
        if(method->type->outtuple > 0) {
                n = nod(ORETURN, N, N);
-               n->list = fn->nbody;
-               fn->nbody = list1(n);
+               n->list = list1(call);
+               call = n;
        }
+       fn->nbody = list(fn->nbody, call);
 
        if(0 && debug['r'])
                dumplist("genwrapper body", fn->nbody);
index 289d78f49f7038228148c33af367857213c95598..6c37f888f20b32b6577c20c94c4d3fd0a38e9fe3 100644 (file)
@@ -131,3 +131,8 @@ func printany(i interface{}) {
                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")
+}