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)