shithub: mc

Download patch

ref: 927294f0ffc7029440111a48200aa2d476545650
parent: 1cb86ecfd69335631474bea4bb8a102e4559408a
author: Ori Bernstein <[email protected]>
date: Fri May 8 16:22:21 EDT 2015

Use before def checking is closer to working.

    Reduce spurious errors.

--- a/6/isel.c
+++ b/6/isel.c
@@ -778,6 +778,7 @@
             break;
         case Odead:
         case Oundef:
+        case Odef:
             /* nothing */
             break;
 
--- a/6/simp.c
+++ b/6/simp.c
@@ -70,6 +70,21 @@
 Type *tyvoid;
 Node *abortoob;
 
+static void append(Simp *s, Node *n)
+{
+    lappend(&s->stmts, &s->nstmts, n);
+}
+
+static int ispure(Node *n)
+{
+    return opispure[exprop(n)];
+}
+
+static int isconstfn(Node *s)
+{
+    return s->decl.isconst && decltype(s)->type == Tyfunc;
+}
+
 size_t alignto(size_t sz, Type *t)
 {
     size_t a;
@@ -253,6 +268,15 @@
     return n;
 }
 
+static void def(Simp *s, Node *var)
+{
+    Node *d;
+
+    d = mkexpr(var->loc, Odef, var, NULL);
+    d->expr.type = mktype(var->loc, Tyvoid);
+    append(s, d);
+}
+
 static Node *disp(Srcloc loc, uint v)
 {
     Node *n;
@@ -271,21 +295,6 @@
     return n;
 }
 
-static void append(Simp *s, Node *n)
-{
-    lappend(&s->stmts, &s->nstmts, n);
-}
-
-static int ispure(Node *n)
-{
-    return opispure[exprop(n)];
-}
-
-static int isconstfn(Node *s)
-{
-    return s->decl.isconst && decltype(s)->type == Tyfunc;
-}
-
 static Node *gentemp(Simp *simp, Node *e, Type *ty, Node **dcl)
 {
     char buf[128];
@@ -470,6 +479,7 @@
     append(s, assign(s, idx, zero));
     jmp(s, lcond);
     simp(s, lbody);
+
     /* body */
     simp(s, n->iterstmt.body);
     /* step */
@@ -1363,6 +1373,9 @@
         case Ostruct:
             if (!dst)
                 dst = temp(s, n);
+            u = mkexpr(dst->loc, Odef, dst, NULL);
+            u->expr.type = mktype(u->loc, Tyvoid);
+            append(s, u);
             t = addr(s, dst, exprtype(dst));
             ty = exprtype(n);
             /* we only need to clear if we don't have things fully initialized */
@@ -1475,8 +1488,13 @@
                 else
                     r = temp(s, n);
                 linsert(&n->expr.args, &n->expr.nargs, 1, addr(s, r, exprtype(n)));
-                for (i = 0; i < n->expr.nargs; i++)
+                for (i = 0; i < n->expr.nargs; i++) {
                     n->expr.args[i] = rval(s, n->expr.args[i], NULL);
+                    if (exprop(n->expr.args[i]) == Oaddr)
+                        if (exprop(n->expr.args[i]->expr.args[0]) == Ovar)
+                            def(s, n->expr.args[i]->expr.args[0]);
+                }
+                def(s, r);
                 append(s, n);
             } else {
                 r = visit(s, n);
@@ -1588,18 +1606,16 @@
         case Ndecl:
             declarelocal(s, n);
             t = mkexpr(n->loc, Ovar, n->decl.name, NULL);
-            if (!n->decl.init) {
-                u = mkexpr(n->loc, Oundef, t, NULL);
-                u->expr.type = mktype(n->loc, Tyvoid);
-            } else {
+            if (n->decl.init) {
                 u = mkexpr(n->loc, Oasn, t, n->decl.init, NULL);
                 u->expr.type = n->decl.type;
+                t->expr.type = n->decl.type;
+                t->expr.did = n->decl.did;
+                simp(s, u);
             }
-            t->expr.type = n->decl.type;
-            t->expr.did = n->decl.did;
-            simp(s, u);
             break;
         default:
+            dump(n, stderr);
             die("bad node passsed to simp()");
             break;
     }
--- a/mi/dfcheck.c
+++ b/mi/dfcheck.c
@@ -17,6 +17,7 @@
 {
     size_t i, j, did;
     Node *def;
+    Type *t;
 
     if (n->type != Nexpr)
         return;
@@ -23,6 +24,9 @@
     if (exprop(n) == Ovar) {
         did = n->expr.did;
         for (j = 0; j < r->ndefs[did]; j++) {
+            t = tybase(exprtype(n));
+            if (t->type == Tystruct || t->type == Tyunion || t->type == Tyarray || t->type == Tytuple)
+                continue;
             if (bshas(kill, r->defs[did][j]))
                 continue;
             if (!bshas(reach, r->defs[did][j]))
@@ -38,6 +42,17 @@
             case Oblit:
                 checkundef(n->expr.args[1], r, reach, kill);
                 break;
+            case Oaddr:
+            case Oslice:
+                /* these don't actually look at the of args[0], so they're ok. */
+                for (i = 1; i < n->expr.nargs; i++)
+                    checkundef(n->expr.args[i], r, reach, kill);
+                break;
+            case Ocall:
+                for (i = 1; i < n->expr.nargs; i++)
+                    if (exprop(n->expr.args[i]) != Oaddr)
+                        checkundef(n->expr.args[i], r, reach, kill);
+                break;
             default:
                 for (i = 0; i < n->expr.nargs; i++)
                     checkundef(n->expr.args[i], r, reach, kill);
@@ -55,8 +70,11 @@
     Bb *bb;
 
     r = reaching(cfg);
+//    dumpcfg(cfg, stdout);
     for (i = 0; i < cfg->nbb; i++) {
         bb = cfg->bb[i];
+        if (!bb)
+            continue;
         reach = bsdup(r->in[i]);
         kill = mkbs();
         for (j = 0; j < bb->nnl; j++) {
@@ -110,6 +128,5 @@
 void check(Cfg *cfg)
 {
     checkret(cfg);
-    if (0)
-        checkreach(cfg);
+    if(0) checkreach(cfg);
 }
--- a/mi/reaching.c
+++ b/mi/reaching.c
@@ -18,7 +18,7 @@
     Node *a;
 
     switch (exprop(n)) {
-        case Oundef:
+        case Oundef: case Odef:
         case Oset:
         case Oasn: case Oaddeq:
         case Osubeq: case Omuleq:
@@ -29,10 +29,11 @@
             return n->expr.args[0];
             break;
         case Oblit:
+        case Oclear:
             a = n->expr.args[0];
             if (exprop(a) != Oaddr)
                 break;
-            a = n->expr.args[0];
+            a = a->expr.args[0];
             if (exprop(a) != Ovar)
                 break;
             return a;
@@ -156,7 +157,7 @@
 //        printf("\tout: ");
 //        bsdump(out[i]);
 //    }
-//
+
     reaching = xalloc(sizeof(Reaching));
     reaching->in = in;
     reaching->out = out;
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -876,10 +876,19 @@
 
 blkbody : decl {
                 size_t i;
+                Node *n, *d, *u;
+
                 $$ = mkblock($1.loc, mkstab());
                 for (i = 0; i < $1.nn; i++) {
-                    putdcl($$->block.scope, $1.nl[i]);
-                    lappend(&$$->block.stmts, &$$->block.nstmts, $1.nl[i]);
+                    d = $1.nl[i];
+                    putdcl($$->block.scope, d);
+                    if (!d->decl.init) {
+                        n = mkexpr(d->loc, Ovar, d->decl.name, NULL);
+                        u = mkexpr(n->loc, Oundef, n, NULL);
+                        n->expr.did = d->decl.did;
+                        lappend(&$$->block.stmts, &$$->block.nstmts, u);
+                    }
+                    lappend(&$$->block.stmts, &$$->block.nstmts, d);
                 }
             }
         | stmt {
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1448,8 +1448,15 @@
             }
             settype(st, n, type(st, args[0]));
             break;
+        case Oundef:
+            infersub(st, n, ret, sawret, &isconst);
+            settype(st, n, mktype(n->loc, Tyvoid));
+            break;
+        case Odef:
+        case Odead:
+            n->expr.type = mktype(n->loc, Tyvoid);
+            break;
         case Obad: case Ocjmp: case Ojtab: case Oset:
-        case Odead: case Oundef:
         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
@@ -58,6 +58,7 @@
 /* all below this point are backend-only */
 O(Odead,        0,      OTmisc, "DEAD")         /* dead code */
 O(Oundef,       0,      OTmisc, "UNDEF")        /* undefined var */
+O(Odef,         0,      OTmisc, "DEF")          /* defined var */
 O(Ocjmp,	1,	OTmisc, "CJMP")         /* conditional jump */
 O(Ojtab,	1,	OTmisc, "JTAB")		/* jump table */
 O(Oset,	        1,	OTbin,  "=")            /* store to var */
--- a/test/derefassign.myr
+++ b/test/derefassign.myr
@@ -4,6 +4,7 @@
 	var p
 	var v
 
+	v = 0
 	p = &v
 	p# = 123
 	std.exit(v)