]> Cypherpunks repositories - gostls13.git/commitdiff
implement discussed function wo return statement
authorKen Thompson <ken@golang.org>
Thu, 11 Sep 2008 22:23:01 +0000 (15:23 -0700)
committerKen Thompson <ken@golang.org>
Thu, 11 Sep 2008 22:23:01 +0000 (15:23 -0700)
R=r
OCL=15166
CL=15166

src/cmd/6g/gen.c
src/cmd/gc/walk.c

index dbdafd612797a43383787bb82dcaf977a113d05b..9751402ad566edb15779db11f25f67f99c6f8401 100644 (file)
@@ -68,8 +68,10 @@ if(newproc == N) {
        gclean();
        checklabels();
 
-//     if(curfn->type->outtuple != 0)
-//             gins(AGOK, N, N);
+       if(curfn->type->outtuple != 0) {
+               nodconst(&nod1, types[TUINT8], 6); // 6 is opcode trap
+               gins(AINT, &nod1, N);
+       }
 
        pc->as = ARET;  // overwrite AEND
        pc->lineno = lineno;
index 8612f6d1303b59deb1e4e2ee935a6842257a018c..abb7ce0bd808e5f6085619010b1eaf4ac332a909 100644 (file)
@@ -10,6 +10,38 @@ static       Type*   sw3(Node*, Type*);
 static Node*   curfn;
 static Node*   addtop;
 
+// can this code branch reach the end
+// without an undcontitional RETURN
+// this is hard, so it is conservative
+int
+walkret(Node *n)
+{
+
+loop:
+       if(n != N)
+       switch(n->op) {
+       case OLIST:
+               if(n->right == N) {
+                       n = n->left;
+                       goto loop;
+               }
+               n = n->right;
+               goto loop;
+
+       // at this point, we have the last
+       // statement of the function
+
+       case OGOTO:
+       case OPANIC:
+       case ORETURN:
+               return 0;
+       }
+
+       // all other statements
+       // will flow to the end
+       return 1;
+}
+
 void
 walk(Node *fn)
 {
@@ -18,12 +50,15 @@ walk(Node *fn)
        curfn = fn;
        if(debug['W']) {
                snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
-               dump(s, fn->nbody);
+               dump(s, curfn->nbody);
        }
-       walkstate(fn->nbody);
+       if(curfn->type->outtuple)
+               if(walkret(curfn->nbody))
+                       warn("function ends without a return statement");
+       walkstate(curfn->nbody);
        if(debug['W']) {
                snprint(s, sizeof(s), "after %S", curfn->nname->sym);
-               dump(s, fn->nbody);
+               dump(s, curfn->nbody);
        }
 }