summaryrefslogtreecommitdiff
path: root/src/cmd/cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/cc')
-rw-r--r--src/cmd/cc/acid.c1
-rw-r--r--src/cmd/cc/bits.c1
-rw-r--r--src/cmd/cc/cc.h4
-rw-r--r--src/cmd/cc/cc.y1
-rw-r--r--src/cmd/cc/com.c3
-rw-r--r--src/cmd/cc/com64.c1
-rw-r--r--src/cmd/cc/dcl.c2
-rw-r--r--src/cmd/cc/dpchk.c129
-rw-r--r--src/cmd/cc/funct.c1
-rw-r--r--src/cmd/cc/godefs.c3
-rw-r--r--src/cmd/cc/lex.c8
-rw-r--r--src/cmd/cc/lexbody6
-rw-r--r--src/cmd/cc/mac.c2
-rw-r--r--src/cmd/cc/macbody6
-rw-r--r--src/cmd/cc/omachcap.c2
-rw-r--r--src/cmd/cc/pgen.c2
-rw-r--r--src/cmd/cc/scon.c1
-rw-r--r--src/cmd/cc/sub.c1
18 files changed, 144 insertions, 30 deletions
diff --git a/src/cmd/cc/acid.c b/src/cmd/cc/acid.c
index c6a6722bd..23147e519 100644
--- a/src/cmd/cc/acid.c
+++ b/src/cmd/cc/acid.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
static char *kwd[] =
diff --git a/src/cmd/cc/bits.c b/src/cmd/cc/bits.c
index aef4449e8..4496d65e7 100644
--- a/src/cmd/cc/bits.c
+++ b/src/cmd/cc/bits.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
Bits
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index 8e8f6af44..a38e658ce 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -28,10 +28,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include <u.h>
#include <libc.h>
#include <bio.h>
-#include <ctype.h>
#pragma lib "../cc/cc.a$O"
@@ -816,7 +814,9 @@ int machcap(Node*);
#pragma varargck type "L" int32
#pragma varargck type "Q" int32
#pragma varargck type "O" int
+#pragma varargck type "O" uint
#pragma varargck type "T" Type*
+#pragma varargck type "U" char*
#pragma varargck type "|" int
enum
diff --git a/src/cmd/cc/cc.y b/src/cmd/cc/cc.y
index 470fdae26..515a80372 100644
--- a/src/cmd/cc/cc.y
+++ b/src/cmd/cc/cc.y
@@ -29,6 +29,7 @@
// THE SOFTWARE.
%{
+#include <u.h>
#include <stdio.h> /* if we don't, bison will, and cc.h re-#defines getc */
#include "cc.h"
%}
diff --git a/src/cmd/cc/com.c b/src/cmd/cc/com.c
index b1a8a4704..6e470ee64 100644
--- a/src/cmd/cc/com.c
+++ b/src/cmd/cc/com.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
int compar(Node*, int);
@@ -127,7 +128,7 @@ tcomo(Node *n, int f)
case ORETURN:
if(l == Z) {
if(n->type->etype != TVOID)
- warn(n, "null return of a typed function");
+ diag(n, "null return of a typed function");
break;
}
if(tcom(l))
diff --git a/src/cmd/cc/com64.c b/src/cmd/cc/com64.c
index 8d6e07d1b..fb7a3f750 100644
--- a/src/cmd/cc/com64.c
+++ b/src/cmd/cc/com64.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
/*
diff --git a/src/cmd/cc/dcl.c b/src/cmd/cc/dcl.c
index d7604b649..d624bf247 100644
--- a/src/cmd/cc/dcl.c
+++ b/src/cmd/cc/dcl.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
Node*
@@ -1378,7 +1379,6 @@ tmerge(Type *t1, Sym *s)
Type *ta, *tb, *t2;
t2 = s->type;
-/*print("merge %T; %T\n", t1, t2);/**/
for(;;) {
if(t1 == T || t2 == T || t1 == t2)
break;
diff --git a/src/cmd/cc/dpchk.c b/src/cmd/cc/dpchk.c
index 0e51101f1..42c245b56 100644
--- a/src/cmd/cc/dpchk.c
+++ b/src/cmd/cc/dpchk.c
@@ -28,6 +28,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
+#include <ctype.h>
#include "cc.h"
#include "y.tab.h"
@@ -56,7 +58,9 @@ struct Tname
{
char* name;
int param;
+ int count;
Tname* link;
+ Tprot* prot;
};
static Type* indchar;
@@ -131,8 +135,8 @@ getflag(char *s)
return flag;
}
-void
-newprot(Sym *m, Type *t, char *s)
+static void
+newprot(Sym *m, Type *t, char *s, Tprot **prot)
{
Bits flag;
Tprot *l;
@@ -142,32 +146,37 @@ newprot(Sym *m, Type *t, char *s)
return;
}
flag = getflag(s);
- for(l=tprot; l; l=l->link)
+ for(l=*prot; l; l=l->link)
if(beq(flag, l->flag) && sametype(t, l->type))
return;
l = alloc(sizeof(*l));
l->type = t;
l->flag = flag;
- l->link = tprot;
- tprot = l;
+ l->link = *prot;
+ *prot = l;
}
-void
-newname(char *s, int p)
+static Tname*
+newname(char *s, int p, int count)
{
Tname *l;
for(l=tname; l; l=l->link)
if(strcmp(l->name, s) == 0) {
- if(l->param != p)
+ if(p >= 0 && l->param != p)
yyerror("vargck %s already defined\n", s);
- return;
+ return l;
}
+ if(p < 0)
+ return nil;
+
l = alloc(sizeof(*l));
l->name = s;
l->param = p;
l->link = tname;
+ l->count = count;
tname = l;
+ return l;
}
void
@@ -234,6 +243,7 @@ pragvararg(void)
int n, c;
char *t;
Type *ty;
+ Tname *l;
if(!debug['F'])
goto out;
@@ -244,6 +254,8 @@ pragvararg(void)
goto cktype;
if(s && strcmp(s->name, "flag") == 0)
goto ckflag;
+ if(s && strcmp(s->name, "countpos") == 0)
+ goto ckcount;
yyerror("syntax in #pragma varargck");
goto out;
@@ -255,7 +267,18 @@ ckpos:
n = getnsn();
if(n < 0)
goto bad;
- newname(s->name, n);
+ newname(s->name, n, 0);
+ goto out;
+
+ckcount:
+/*#pragma varargck countpos name 2*/
+ s = getsym();
+ if(s == S)
+ goto bad;
+ n = getnsn();
+ if(n < 0)
+ goto bad;
+ newname(s->name, 0, n);
goto out;
ckflag:
@@ -276,6 +299,25 @@ ckflag:
goto out;
cktype:
+ c = getnsc();
+ unget(c);
+ if(c != '"') {
+/*#pragma varargck type name int*/
+ s = getsym();
+ if(s == S)
+ goto bad;
+ l = newname(s->name, -1, -1);
+ s = getsym();
+ if(s == S)
+ goto bad;
+ ty = s->type;
+ while((c = getnsc()) == '*')
+ ty = typ(TIND, ty);
+ unget(c);
+ newprot(s, ty, "a", &l->prot);
+ goto out;
+ }
+
/*#pragma varargck type O int*/
t = getquoted();
if(t == nil)
@@ -287,7 +329,7 @@ cktype:
while((c = getnsc()) == '*')
ty = typ(TIND, ty);
unget(c);
- newprot(s, ty, t);
+ newprot(s, ty, t, &tprot);
goto out;
bad:
@@ -384,7 +426,8 @@ dpcheck(Node *n)
char *s;
Node *a, *b;
Tname *l;
- int i;
+ Tprot *tl;
+ int i, j;
if(n == Z)
return;
@@ -398,20 +441,76 @@ dpcheck(Node *n)
if(l == 0)
return;
+ if(l->count > 0) {
+ // fetch count, then check remaining length
+ i = l->count;
+ a = nil;
+ b = n->right;
+ while(i > 0) {
+ b = nextarg(b, &a);
+ i--;
+ }
+ if(a == Z) {
+ diag(n, "can't find count arg");
+ return;
+ }
+ if(a->op != OCONST || !typechl[a->type->etype]) {
+ diag(n, "count is invalid constant");
+ return;
+ }
+ j = a->vconst;
+ i = 0;
+ while(b != Z) {
+ b = nextarg(b, &a);
+ i++;
+ }
+ if(i != j)
+ diag(n, "found %d argument%s after count %d", i, i == 1 ? "" : "s", j);
+ }
+
+ if(l->prot != nil) {
+ // check that all arguments after param or count
+ // are listed in type list.
+ i = l->count;
+ if(i == 0)
+ i = l->param;
+ if(i == 0)
+ return;
+ a = nil;
+ b = n->right;
+ while(i > 0) {
+ b = nextarg(b, &a);
+ i--;
+ }
+ if(a == Z) {
+ diag(n, "can't find count/param arg");
+ return;
+ }
+ while(b != Z) {
+ b = nextarg(b, &a);
+ for(tl=l->prot; tl; tl=tl->link)
+ if(sametype(a->type, tl->type))
+ break;
+ if(tl == nil)
+ diag(a, "invalid type %T in call to %s", a->type, s);
+ }
+ }
+
+ if(l->param <= 0)
+ return;
i = l->param;
a = nil;
b = n->right;
- a = Z;
while(i > 0) {
b = nextarg(b, &a);
i--;
}
if(a == Z) {
- warn(n, "cant find format arg");
+ diag(n, "can't find format arg");
return;
}
if(!sametype(indchar, a->type)) {
- warn(n, "format arg type %T", a->type);
+ diag(n, "format arg type %T", a->type);
return;
}
if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) {
diff --git a/src/cmd/cc/funct.c b/src/cmd/cc/funct.c
index 21d86258f..99477b2b2 100644
--- a/src/cmd/cc/funct.c
+++ b/src/cmd/cc/funct.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
typedef struct Ftab Ftab;
diff --git a/src/cmd/cc/godefs.c b/src/cmd/cc/godefs.c
index 9503cb2f2..3ba979c8a 100644
--- a/src/cmd/cc/godefs.c
+++ b/src/cmd/cc/godefs.c
@@ -29,6 +29,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
static int upper;
@@ -238,7 +239,7 @@ printtypename(Type *t)
Bprint(&outbuf, "%U", n);
break;
case TFUNC:
- Bprint(&outbuf, "func(", t);
+ Bprint(&outbuf, "func(");
for(t1 = t->down; t1 != T; t1 = t1->down) {
if(t1->etype == TVOID)
break;
diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c
index 71cc89bf0..15f2d374d 100644
--- a/src/cmd/cc/lex.c
+++ b/src/cmd/cc/lex.c
@@ -28,6 +28,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
+#include <ctype.h>
#include "cc.h"
#include "y.tab.h"
@@ -384,7 +386,7 @@ lookup(void)
}else
*w++ = *r;
}
- *w++ = '\0';
+ *w = '\0';
h = 0;
for(p=symb; *p;) {
@@ -1524,7 +1526,7 @@ alloc(int32 n)
p = malloc(n);
if(p == nil) {
print("alloc out of mem\n");
- exit(1);
+ exits("alloc: out of mem");
}
memset(p, 0, n);
return p;
@@ -1538,7 +1540,7 @@ allocn(void *p, int32 n, int32 d)
p = realloc(p, n+d);
if(p == nil) {
print("allocn out of mem\n");
- exit(1);
+ exits("allocn: out of mem");
}
if(d > 0)
memset((char*)p+n, 0, d);
diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody
index 24f9bdc85..f4cc19c2e 100644
--- a/src/cmd/cc/lexbody
+++ b/src/cmd/cc/lexbody
@@ -96,7 +96,7 @@ alloc(int32 n)
p = malloc(n);
if(p == nil) {
print("alloc out of mem\n");
- exit(1);
+ exits("alloc: out of mem");
}
memset(p, 0, n);
return p;
@@ -110,7 +110,7 @@ allocn(void *p, int32 n, int32 d)
p = realloc(p, n+d);
if(p == nil) {
print("allocn out of mem\n");
- exit(1);
+ exits("allocn: out of mem");
}
if(d > 0)
memset((char*)p+n, 0, d);
@@ -245,7 +245,7 @@ lookup(void)
}else
*w++ = *r;
}
- *w++ = '\0';
+ *w = '\0';
h = 0;
for(p=symb; c = *p; p++)
diff --git a/src/cmd/cc/mac.c b/src/cmd/cc/mac.c
index c08cd9c97..43ae214d7 100644
--- a/src/cmd/cc/mac.c
+++ b/src/cmd/cc/mac.c
@@ -28,6 +28,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
+#include <ctype.h>
#include "cc.h"
#include "macbody"
diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody
index ca8a54c0b..ed66361f1 100644
--- a/src/cmd/cc/macbody
+++ b/src/cmd/cc/macbody
@@ -830,11 +830,11 @@ linehist(char *f, int offset)
if(debug['f'])
if(f) {
if(offset)
- print("%4ld: %s (#line %d)\n", lineno, f, offset);
+ print("%4d: %s (#line %d)\n", lineno, f, offset);
else
- print("%4ld: %s\n", lineno, f);
+ print("%4d: %s\n", lineno, f);
} else
- print("%4ld: <pop>\n", lineno);
+ print("%4d: <pop>\n", lineno);
newflag = 0;
h = alloc(sizeof(Hist));
diff --git a/src/cmd/cc/omachcap.c b/src/cmd/cc/omachcap.c
index ec5aa86e9..f8fc1d88b 100644
--- a/src/cmd/cc/omachcap.c
+++ b/src/cmd/cc/omachcap.c
@@ -28,11 +28,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
/* default, like old cc */
int
machcap(Node *n)
{
+ USED(n);
return 0;
}
diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c
index 5d17cafc9..0e5e8c059 100644
--- a/src/cmd/cc/pgen.c
+++ b/src/cmd/cc/pgen.c
@@ -112,7 +112,7 @@ codgen(Node *n, Node *nn)
warnreach = 1;
gen(n);
if(canreach && thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", n1->sym->name);
+ diag(Z, "no return at end of function: %s", n1->sym->name);
noretval(3);
gbranch(ORETURN);
diff --git a/src/cmd/cc/scon.c b/src/cmd/cc/scon.c
index 3047ca44f..193331f77 100644
--- a/src/cmd/cc/scon.c
+++ b/src/cmd/cc/scon.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
static Node*
diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c
index e0d5df719..e5992e213 100644
--- a/src/cmd/cc/sub.c
+++ b/src/cmd/cc/sub.c
@@ -28,6 +28,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+#include <u.h>
#include "cc.h"
Node*