shithub: mc

Download patch

ref: ccee477034a0a63df7a5864b375a243f8e4f246a
parent: 685513dd421ded344ae4a4e2c498928fbdbb00aa
author: Ori Bernstein <[email protected]>
date: Wed May 6 14:13:50 EDT 2015

Compile error on reaching end of func without return.

--- a/6/gen.c
+++ b/6/gen.c
@@ -40,7 +40,6 @@
     return buf;
 }
 
-
 /* 
  * For x86, the assembly names are generated as follows:
  *      local symbols: .name
--- a/6/isel.c
+++ b/6/isel.c
@@ -776,6 +776,9 @@
             else
                 g(s, Icvttss2sd, a, r, NULL);
             break;
+        case Odead:
+            /* nothing */
+            break;
 
         /* These operators should never show up in the reduced trees,
          * since they should have been replaced with more primitive
--- a/6/simp.c
+++ b/6/simp.c
@@ -661,6 +661,7 @@
         jmp(s, end);
         append(s, next);
     }
+    append(s, mkexpr(n->loc, Odead, NULL));
     append(s, end);
 }
 
@@ -1675,8 +1676,7 @@
     }
 
     cfg = mkcfg(dcl, s->stmts, s->nstmts);
-    if (extracheck)
-       check(cfg);
+    check(cfg);
     if (debugopt['t'] || debugopt['s'])
         dumpcfg(cfg, stdout);
 
--- a/libbio/puti.myr
+++ b/libbio/puti.myr
@@ -40,7 +40,7 @@
 	buf[5] = (v >> 40) & 0xff castto(byte)
 	buf[6] = (v >> 48) & 0xff castto(byte)
 	buf[7] = (v >> 56) & 0xff castto(byte)
-	write(f, buf[:n])
+	-> write(f, buf[:n])
 }
 
 const putbe = {f, v, n
@@ -57,6 +57,6 @@
 	buf[5] = (v >> 16) & 0xff castto(byte)
 	buf[6] = (v >> 8) & 0xff castto(byte)
 	buf[7] = (v >> 0) & 0xff castto(byte)
-	write(f, buf[8-n:])
+	-> write(f, buf[8-n:])
 }
 
--- a/libstd/getcwd.myr
+++ b/libstd/getcwd.myr
@@ -25,5 +25,7 @@
 			len *= 2
 		;;
 	;;
+	/* unreachable; shut up return without value analysis */
+	-> ""
 }
 	
--- a/libstd/htab.myr
+++ b/libstd/htab.myr
@@ -90,6 +90,7 @@
 			-> `Some i
 		;;
 	;;
+	-> `None /* fixme; while true should flag this as unreachable */
 }
 
 generic mkht = {h, eq
--- a/libstd/spork.myr
+++ b/libstd/spork.myr
@@ -52,9 +52,8 @@
 		;;
 		close(infd)
 		close(outfd)
-		if execvp(cmd[0], cmd) < 0
-			fatal(1, "failed to exec %s\n")
-		;;
+		execvp(cmd[0], cmd) < 0
+		fatal(1, "failed to exec %s\n")
 	/* parent */
 	else
 		-> `Ok pid
--- a/libstd/sys+linux-x64.myr
+++ b/libstd/sys+linux-x64.myr
@@ -43,6 +43,7 @@
 		`Waitexit int32
 		`Waitsig  int32
 		`Waitstop int32
+		`Waitfail int32
 	;;
 
 	type timespec = struct
@@ -796,4 +797,5 @@
 	elif (((st & 0xffff)*0x10001)>>8) > 0x7f00
 		-> `Waitstop ((st & 0xff00) >> 8)
 	;;
+	-> `Waitfail st	/* wait failed to give a result */
 }
--- a/libstd/wait+posixy.myr
+++ b/libstd/wait+posixy.myr
@@ -26,6 +26,7 @@
 		a process exits. Loop instead.
 		*/
 		| `sys.Waitstop sig:	goto again
+		| `sys.Waitfail fail:	-> `Waiterror
 		| `sys.Waitsig sig:	-> `Wsignalled
 		| `sys.Waitexit status:
 			if status == 0
--- a/mbld/deps.myr
+++ b/mbld/deps.myr
@@ -214,6 +214,7 @@
 			-> deps
 		;;
 	;;
+	std.die("unreachable")
 }
 
 const scrapelibs = {dg, lib, incs
--- a/mi/cfg.c
+++ b/mi/cfg.c
@@ -124,10 +124,20 @@
     cfg->bb[bb->id] = NULL;
 }
 
-void trimdead(Bb *bb)
+void noexit(Cfg *cfg, Bb *bb)
 {
     size_t i;
+    for (i = 0; bsiter(bb->succ, &i); i++)
+        bsdel(cfg->bb[i]->pred, bb->id);
+    bsclear(bb->succ);
+}
 
+void trimdead(Cfg *cfg, Bb *bb)
+{
+    size_t i;
+
+    if (!bb)
+        return;
     for (i = 0; i < bb->nnl; i++) {
         switch (exprop(bb->nl[i])) {
             /* if we're jumping, we can't keep going
@@ -137,11 +147,17 @@
             case Oret:
                 bb->nnl = i + 1;
                 return;
-            case Ocall:
-                if (!isnonretcall(bb->nl[i]->expr.args[0]))
-                    break;
+            case Odead:
+                noexit(cfg, bb);
                 bb->nnl = i + 1;
                 return;
+            case Ocall:
+                if (isnonretcall(bb->nl[i]->expr.args[0])) {
+                    noexit(cfg, bb);
+                    bb->nnl = i + 1;
+                    return;
+                }
+                break;
             default:
                 /* nothing */
                 break;
@@ -153,22 +169,6 @@
 {
     Bb *bb;
     size_t i;
-
-    /* delete empty blocks and trivially unreachable code */
-    for (i = 0; i < cfg->nbb; i++) {
-
-        bb = cfg->bb[i];
-        if (bb->nnl == 0)
-            delete(cfg, bb);
-        else
-            trimdead(bb);
-    }
-}
-
-void delunreachable(Cfg *cfg)
-{
-    Bb *bb;
-    size_t i;
     int deleted;
 
     deleted = 1;
@@ -178,6 +178,7 @@
             bb = cfg->bb[i];
             if (bb == cfg->start || bb == cfg->end)
                 continue;
+            trimdead(cfg, bb);
             if (bb && bsisempty(bb->pred)) {
                 delete(cfg, bb);
                 deleted = 1;
@@ -192,6 +193,8 @@
     Bb *pre, *post;
     Bb *bb, *targ;
     Node *a, *b;
+    static int nextret;
+    char buf[32];
     size_t i;
 
     cfg = zalloc(sizeof(Cfg));
@@ -215,6 +218,9 @@
         }
     }
     post = mkbb(cfg);
+    snprintf(buf, sizeof buf, ".R%d", nextret++);
+    label(cfg, mklbl(fn->loc, buf), post);
+
     cfg->start = pre;
     cfg->end = post;
     bsput(pre->succ, cfg->bb[1]->id);
@@ -221,7 +227,6 @@
     bsput(cfg->bb[1]->pred, pre->id);
     bsput(cfg->bb[cfg->nbb - 2]->succ, post->id);
     bsput(post->pred, cfg->bb[cfg->nbb - 2]->id);
-    trim(cfg);
 
     for (i = 0; i < cfg->nfixjmp; i++) {
         bb = cfg->fixblk[i];
@@ -257,7 +262,7 @@
             bsput(targ->pred, bb->id);
         }
     }
-    delunreachable(cfg);
+    trim(cfg);
     return cfg;
 }
 
--- a/mi/dfcheck.c
+++ b/mi/dfcheck.c
@@ -38,6 +38,7 @@
 static void checkpredret(Cfg *cfg, Bb *bb)
 {
     Bb *pred;
+    Op op;
     size_t i;
 
     for (i = 0; bsiter(bb->pred, &i); i++) {
@@ -44,9 +45,11 @@
         pred = cfg->bb[i];
         if (pred->nnl == 0) {
             checkpredret(cfg, pred);
-        } else if (exprop(pred->nl[pred->nnl - 1]) != Oret) {
-            dumpcfg(cfg, stdout);
-            fatal(pred->nl[pred->nnl-1], "Reaches end of function without return\n");
+        } else {
+            op = exprop(pred->nl[pred->nnl - 1]);
+            if (op != Oret && op != Odead) {
+                fatal(pred->nl[pred->nnl-1], "Reaches end of function without return\n");
+            }
         }
     }
 }
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1446,7 +1446,7 @@
             }
             settype(st, n, type(st, args[0]));
             break;
-        case Obad: case Ocjmp: case Ojtab: case Oset:
+        case Obad: case Ocjmp: case Ojtab: case Oset: case Odead:
         case Oslbase: case Osllen: case Outag:
         case Oblit: case  Oclear: case Oudata:
         case Otrunc: case Oswiden: case Ozwiden:
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -56,8 +56,9 @@
 O(Oarr,	        1,	OTmisc, NULL)
 
 /* all below this point are backend-only */
-O(Ocjmp,	1,	OTmisc, NULL)           /* conditional jump */
-O(Ojtab,	1,	OTmisc, NULL)		/* jump table */
+O(Odead,        0,      OTmisc, "DEAD")         /* unreachable code */
+O(Ocjmp,	1,	OTmisc, "CJMP")         /* conditional jump */
+O(Ojtab,	1,	OTmisc, "JTAB")		/* jump table */
 O(Oset,	        1,	OTbin,  "=")            /* store to var */
 O(Osllen,	1,	OTpre,  "SLLEN")        /* size of slice */
 O(Oslbase,	1,	OTpre,  "SLBASE")       /* base of sice */