merge in latest Linton version
[unix-history] / usr / src / old / dbx / check.c
index baec10b..ebcc542 100644 (file)
@@ -1,6 +1,14 @@
-/* Copyright (c) 1982 Regents of the University of California */
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
 
 
-static char sccsid[] = "@(#)check.c 1.2 %G%";
+#ifndef lint
+static char sccsid[] = "@(#)check.c    5.2 (Berkeley) %G%";
+#endif not lint
+
+static char rcsid[] = "$Header: check.c,v 1.5 84/12/26 10:38:35 linton Exp $";
 
 /*
  * Check a tree for semantic correctness.
 
 /*
  * Check a tree for semantic correctness.
@@ -16,6 +24,7 @@ static char sccsid[] = "@(#)check.c 1.2 %G%";
 #include "object.h"
 #include "mappings.h"
 #include "process.h"
 #include "object.h"
 #include "mappings.h"
 #include "process.h"
+#include <signal.h>
 
 #ifndef public
 #endif
 
 #ifndef public
 #endif
@@ -30,11 +39,56 @@ static char sccsid[] = "@(#)check.c 1.2 %G%";
 public check(p)
 register Node p;
 {
 public check(p)
 register Node p;
 {
+    Node p1, p2;
     Address addr;
     Symbol f;
 
     checkref(p);
     switch (p->op) {
     Address addr;
     Symbol f;
 
     checkref(p);
     switch (p->op) {
+       case O_ASSIGN:
+           p1 = p->value.arg[0];
+           p2 = p->value.arg[1];
+           if (varIsSet("$unsafeassign")) {
+               if (size(p1->nodetype) != size(p2->nodetype)) {
+                   error("incompatible sizes");
+               }
+           } else if (not compatible(p1->nodetype, p2->nodetype)) {
+               error("incompatible types");
+           }
+           break;
+
+       case O_CATCH:
+       case O_IGNORE:
+           if (p->value.lcon < 0 or p->value.lcon > NSIG) {
+               error("invalid signal number");
+           }
+           break;
+
+       case O_CONT:
+           if (p->value.lcon != DEFSIG and (
+               p->value.lcon < 0 or p->value.lcon > NSIG)
+           ) {
+               error("invalid signal number");
+           }
+           break;
+
+       case O_DUMP:
+           if (p->value.arg[0] != nil) {
+               if (p->value.arg[0]->op == O_SYM) {
+                   f = p->value.arg[0]->value.sym;
+                   if (not isblock(f)) {
+                       error("\"%s\" is not a block", symname(f));
+                   }
+               } else {
+                   beginerrmsg();
+                   fprintf(stderr, "expected a symbol, found \"");
+                   prtree(stderr, p->value.arg[0]);
+                   fprintf(stderr, "\"");
+                   enderrmsg();
+               }
+           }
+           break;
+
        case O_LIST:
            if (p->value.arg[0]->op == O_SYM) {
                f = p->value.arg[0]->value.sym;
        case O_LIST:
            if (p->value.arg[0]->op == O_SYM) {
                f = p->value.arg[0]->value.sym;
@@ -58,6 +112,24 @@ register Node p;
            chkstop(p);
            break;
 
            chkstop(p);
            break;
 
+       case O_CALLPROC:
+       case O_CALL:
+           if (not isroutine(p->value.arg[0]->nodetype)) {
+               beginerrmsg();
+               fprintf(stderr, "\"");
+               prtree(stderr, p->value.arg[0]);
+               fprintf(stderr, "\" not call-able");
+               enderrmsg();
+           }
+           break;
+
+       case O_WHEREIS:
+           if (p->value.arg[0]->op == O_SYM and
+             p->value.arg[0]->value.sym == nil) {
+               error("symbol not defined");
+           }
+           break;
+
        default:
            break;
     }
        default:
            break;
     }
@@ -93,7 +165,7 @@ Node p;
            chkaddr(place);
        }
     } else {
            chkaddr(place);
        }
     } else {
-       if (exp->op != O_RVAL and exp->op != O_SYM) {
+       if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
            error("can't trace expressions");
        }
        chkblock(place);
            error("can't trace expressions");
        }
        chkblock(place);
@@ -113,22 +185,22 @@ Node p;
     place = p->value.arg[1];
     cond = p->value.arg[2];
     if (exp != nil) {
     place = p->value.arg[1];
     cond = p->value.arg[2];
     if (exp != nil) {
-       if (exp->op != O_RVAL and exp->op != O_SYM) {
+       if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
            beginerrmsg();
            fprintf(stderr, "expected variable, found ");
            prtree(stderr, exp);
            enderrmsg();
        }
        chkblock(place);
            beginerrmsg();
            fprintf(stderr, "expected variable, found ");
            prtree(stderr, exp);
            enderrmsg();
        }
        chkblock(place);
-    } else if (cond != nil) {
-       chkblock(place);
-    } else if (place->op == O_SYM) {
-       chkblock(place);
-    } else {
-       if (p->op == O_STOP) {
-           chkline(place);
+    } else if (place != nil) {
+       if (place->op == O_SYM) {
+           chkblock(place);
        } else {
        } else {
-           chkaddr(place);
+           if (p->op == O_STOP) {
+               chkline(place);
+           } else {
+               chkaddr(place);
+           }
        }
     }
 }
        }
     }
 }
@@ -141,13 +213,35 @@ Node p;
 private chkblock(b)
 Node b;
 {
 private chkblock(b)
 Node b;
 {
+    Symbol p, outer;
+
     if (b != nil) {
        if (b->op != O_SYM) {
            beginerrmsg();
            fprintf(stderr, "expected subprogram, found ");
            prtree(stderr, b);
            enderrmsg();
     if (b != nil) {
        if (b->op != O_SYM) {
            beginerrmsg();
            fprintf(stderr, "expected subprogram, found ");
            prtree(stderr, b);
            enderrmsg();
-       } else if (not isblock(b->value.sym) or ismodule(b->value.sym)) {
+       } else if (ismodule(b->value.sym)) {
+           outer = b->value.sym;
+           while (outer != nil) {
+               find(p, outer->name) where p->block == outer endfind(p);
+               if (p == nil) {
+                   outer = nil;
+                   error("\"%s\" is not a subprogram", symname(b->value.sym));
+               } else if (ismodule(p)) {
+                   outer = p;
+               } else {
+                   outer = nil;
+                   b->value.sym = p;
+               }
+           }
+       } else if (
+           b->value.sym->class == VAR and
+           b->value.sym->name == b->value.sym->block->name and
+           b->value.sym->block->class == FUNC
+       ) {
+           b->value.sym = b->value.sym->block;
+       } else if (not isblock(b->value.sym)) {
            error("\"%s\" is not a subprogram", symname(b->value.sym));
        }
     }
            error("\"%s\" is not a subprogram", symname(b->value.sym));
        }
     }