cleanup error handling
This commit is contained in:
parent
beec05cd3b
commit
729aa97b79
10 changed files with 86 additions and 92 deletions
5
all.h
5
all.h
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
|
||||
#define die(...) die_(__FILE__, __VA_ARGS__)
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned short ushort;
|
||||
|
@ -481,7 +482,7 @@ extern char debug['Z'+1];
|
|||
/* util.c */
|
||||
extern Typ typ[NTyp];
|
||||
extern Ins insb[NIns], *curi;
|
||||
void diag(char *) __attribute__((noreturn));
|
||||
void die_(char *, char *, ...) __attribute__((noreturn));
|
||||
void *emalloc(size_t);
|
||||
void *alloc(size_t);
|
||||
void freeall(void);
|
||||
|
@ -522,7 +523,7 @@ extern OpDesc opdesc[NOp];
|
|||
void parse(FILE *, char *, void (Dat *), void (Fn *));
|
||||
void printfn(Fn *, FILE *);
|
||||
void printref(Ref, Fn *, FILE *);
|
||||
void err(char *, ...);
|
||||
void err(char *, ...) __attribute__((noreturn));
|
||||
|
||||
/* mem.c */
|
||||
void memopt(Fn *);
|
||||
|
|
34
copy.c
34
copy.c
|
@ -47,7 +47,6 @@ visitphi(Phi *p, Ref *cp, RList **w)
|
|||
break;
|
||||
}
|
||||
}
|
||||
assert(!req(r, R));
|
||||
update(p->to, r, cp, w);
|
||||
}
|
||||
|
||||
|
@ -65,6 +64,15 @@ visitins(Ins *i, Ref *cp, RList **w)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
subst(Ref *r, Ref *cp, Fn *fn)
|
||||
{
|
||||
if (rtype(*r) == RTmp && req(copyof(*r, cp), R))
|
||||
err("temporary %%%s is used undefined",
|
||||
fn->tmp[r->val].name);
|
||||
*r = copyof(*r, cp);
|
||||
}
|
||||
|
||||
void
|
||||
copy(Fn *fn)
|
||||
{
|
||||
|
@ -93,8 +101,6 @@ copy(Fn *fn)
|
|||
u1 = u + fn->tmp[t].nuse;
|
||||
for (; u<u1; u++)
|
||||
switch (u->type) {
|
||||
default:
|
||||
diag("copy: invalid use");
|
||||
case UPhi:
|
||||
visitphi(u->u.phi, cp, &w);
|
||||
break;
|
||||
|
@ -103,6 +109,8 @@ copy(Fn *fn)
|
|||
break;
|
||||
case UJmp:
|
||||
break;
|
||||
default:
|
||||
die("invalid use %d", u->type);
|
||||
}
|
||||
}
|
||||
for (b=fn->start; b; b=b->link) {
|
||||
|
@ -113,31 +121,19 @@ copy(Fn *fn)
|
|||
continue;
|
||||
}
|
||||
for (a=0; a<p->narg; a++)
|
||||
if (rtype(p->arg[a]) == RTmp) {
|
||||
r = cp[p->arg[a].val];
|
||||
assert(!req(r, R));
|
||||
p->arg[a] = r;
|
||||
}
|
||||
subst(&p->arg[a], cp, fn);
|
||||
pp=&p->link;
|
||||
}
|
||||
for (i=b->ins; i-b->ins < b->nins; i++) {
|
||||
r = cp[i->to.val];
|
||||
r = copyof(i->to, cp);
|
||||
if (!req(r, i->to)) {
|
||||
*i = (Ins){.op = ONop};
|
||||
continue;
|
||||
}
|
||||
for (a=0; a<2; a++)
|
||||
if (rtype(i->arg[a]) == RTmp) {
|
||||
r = cp[i->arg[a].val];
|
||||
assert(!req(r, R));
|
||||
i->arg[a] = r;
|
||||
}
|
||||
}
|
||||
if (rtype(b->jmp.arg) == RTmp) {
|
||||
r = cp[b->jmp.arg.val];
|
||||
assert(!req(r, R));
|
||||
b->jmp.arg = r;
|
||||
subst(&i->arg[a], cp, fn);
|
||||
}
|
||||
subst(&b->jmp.arg, cp, fn);
|
||||
}
|
||||
if (debug['C']) {
|
||||
fprintf(stderr, "\n> Copy information:");
|
||||
|
|
40
emit.c
40
emit.c
|
@ -133,7 +133,7 @@ slot(int s, Fn *fn)
|
|||
|
||||
/* sign extend s using a bitfield */
|
||||
x.i = s;
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
if (x.i < 0)
|
||||
return -4 * x.i;
|
||||
else {
|
||||
|
@ -146,8 +146,6 @@ static void
|
|||
emitcon(Con *con, FILE *f)
|
||||
{
|
||||
switch (con->type) {
|
||||
default:
|
||||
diag("emit: invalid constant");
|
||||
case CAddr:
|
||||
if (con->local)
|
||||
fprintf(f, "%s%s", locprefix, con->label);
|
||||
|
@ -159,6 +157,8 @@ emitcon(Con *con, FILE *f)
|
|||
case CBits:
|
||||
fprintf(f, "%"PRId64, con->bits.i);
|
||||
break;
|
||||
default:
|
||||
die("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,14 +178,14 @@ static Ref
|
|||
getarg(char c, Ins *i)
|
||||
{
|
||||
switch (c) {
|
||||
default:
|
||||
diag("emit: 0, 1, = expected in format");
|
||||
case '0':
|
||||
return i->arg[0];
|
||||
case '1':
|
||||
return i->arg[1];
|
||||
case '=':
|
||||
return i->to;
|
||||
default:
|
||||
die("invalid arg letter %c", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,8 +222,8 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f)
|
|||
}
|
||||
/* fall through */
|
||||
case '-':
|
||||
if (req(i->arg[1], i->to) && !req(i->arg[0], i->to))
|
||||
diag("emit: cannot convert to 2-address");
|
||||
assert((!req(i->arg[1], i->to) || req(i->arg[0], i->to)) &&
|
||||
"cannot convert to 2-address");
|
||||
emitcopy(i->to, i->arg[0], i->cls, fn, f);
|
||||
s++;
|
||||
break;
|
||||
|
@ -238,8 +238,6 @@ Next:
|
|||
} else
|
||||
fputc(c, f);
|
||||
switch ((c = *s++)) {
|
||||
default:
|
||||
diag("emit: invalid escape");
|
||||
case '%':
|
||||
fputc('%', f);
|
||||
break;
|
||||
|
@ -258,8 +256,6 @@ Next:
|
|||
c = *s++;
|
||||
ref = getarg(c, i);
|
||||
switch (rtype(ref)) {
|
||||
default:
|
||||
diag("emit: invalid reference");
|
||||
case RTmp:
|
||||
assert(isreg(ref));
|
||||
fprintf(f, "%%%s", regtoa(ref.val, sz));
|
||||
|
@ -294,6 +290,8 @@ Next:
|
|||
fputc('$', f);
|
||||
emitcon(&fn->con[ref.val], f);
|
||||
break;
|
||||
default:
|
||||
die("unreachable");
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
|
@ -312,8 +310,6 @@ Next:
|
|||
c = *s++;
|
||||
ref = getarg(c, i);
|
||||
switch (rtype(ref)) {
|
||||
default:
|
||||
diag("emit: invalid memory reference");
|
||||
case RAMem:
|
||||
goto Mem;
|
||||
case RSlot:
|
||||
|
@ -327,8 +323,12 @@ Next:
|
|||
assert(isreg(ref));
|
||||
fprintf(f, "(%%%s)", regtoa(ref.val, SLong));
|
||||
break;
|
||||
default:
|
||||
die("unreachable");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
die("invalid format specifier %%%c", c);
|
||||
}
|
||||
goto Next;
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ emitins(Ins i, Fn *fn, FILE *f)
|
|||
/* this linear search should really be a binary
|
||||
* search */
|
||||
if (omap[o].op == NOp)
|
||||
diag("emit: no entry found for instruction");
|
||||
die("not match for %d(%d)", i.op, i.cls);
|
||||
if (omap[o].op == i.op)
|
||||
if (omap[o].cls == i.cls
|
||||
|| (omap[o].cls == Ki && KBASE(i.cls) == 0)
|
||||
|
@ -412,8 +412,6 @@ emitins(Ins i, Fn *fn, FILE *f)
|
|||
/* calls simply have a weird syntax in AT&T
|
||||
* assembly... */
|
||||
switch (rtype(i.arg[0])) {
|
||||
default:
|
||||
diag("emit: invalid call instruction");
|
||||
case RCon:
|
||||
fprintf(f, "\tcallq ");
|
||||
emitcon(&fn->con[i.arg[0].val], f);
|
||||
|
@ -422,6 +420,8 @@ emitins(Ins i, Fn *fn, FILE *f)
|
|||
case RTmp:
|
||||
emitf("callq *%L0", &i, fn, f);
|
||||
break;
|
||||
default:
|
||||
die("invalid call argument");
|
||||
}
|
||||
break;
|
||||
case OSAlloc:
|
||||
|
@ -450,7 +450,7 @@ static int
|
|||
cneg(int cmp)
|
||||
{
|
||||
switch (cmp) {
|
||||
default: diag("emit: cneg() unhandled comparison");
|
||||
default: die("invalid int comparison %d", cmp);
|
||||
case ICule: return ICugt;
|
||||
case ICult: return ICuge;
|
||||
case ICsle: return ICsgt;
|
||||
|
@ -471,7 +471,7 @@ framesz(Fn *fn)
|
|||
{
|
||||
int i, o, f;
|
||||
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
for (i=0, o=0; i<NRClob; i++)
|
||||
o ^= 1 & (fn->reg >> rclob[i]);
|
||||
f = fn->slot;
|
||||
|
@ -549,12 +549,12 @@ emitfn(Fn *fn, FILE *f)
|
|||
c = cneg(c);
|
||||
s = b->s2;
|
||||
} else
|
||||
diag("emit: unhandled jump (1)");
|
||||
die("unhandled jump");
|
||||
fprintf(f, "\tj%s %sbb%d /* %s */\n",
|
||||
ctoa[c], locprefix, id0+s->id, s->name);
|
||||
break;
|
||||
}
|
||||
diag("emit: unhandled jump (2)");
|
||||
die("unhandled jump %d", b->jmp.type);
|
||||
}
|
||||
}
|
||||
id0 += fn->nblk;
|
||||
|
|
48
isel.c
48
isel.c
|
@ -35,7 +35,7 @@ static int
|
|||
fcmptoi(int fc)
|
||||
{
|
||||
switch (fc) {
|
||||
default: diag("isel: fcmptoi defaulted");
|
||||
default: die("invalid fp comparison %d", fc);
|
||||
case FCle: return ICule;
|
||||
case FClt: return ICult;
|
||||
case FCgt: return ICugt;
|
||||
|
@ -85,8 +85,6 @@ noimm(Ref r, Fn *fn)
|
|||
if (rtype(r) != RCon)
|
||||
return 0;
|
||||
switch (fn->con[r.val].type) {
|
||||
default:
|
||||
diag("isel: invalid constant");
|
||||
case CAddr:
|
||||
/* we only support the 'small'
|
||||
* code model of the ABI, this
|
||||
|
@ -97,6 +95,8 @@ noimm(Ref r, Fn *fn)
|
|||
case CBits:
|
||||
val = fn->con[r.val].bits.i;
|
||||
return (val < INT32_MIN || val > INT32_MAX);
|
||||
default:
|
||||
die("invalid constant");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ sel(Ins i, ANum *an, Fn *fn)
|
|||
{
|
||||
Ref r0, r1;
|
||||
int x, k, kc;
|
||||
int64_t val;
|
||||
int64_t sz;
|
||||
Ins *i0;
|
||||
|
||||
if (rtype(i.to) == RTmp)
|
||||
|
@ -308,12 +308,11 @@ Emit:
|
|||
* (rsp = 0) mod 16
|
||||
*/
|
||||
if (rtype(i.arg[0]) == RCon) {
|
||||
assert(fn->con[i.arg[0].val].type == CBits);
|
||||
val = fn->con[i.arg[0].val].bits.i;
|
||||
val = (val + 15) & ~INT64_C(15);
|
||||
if (val < 0 || val > INT32_MAX)
|
||||
diag("isel: alloc too large");
|
||||
emit(OSAlloc, Kl, i.to, getcon(val, fn), R);
|
||||
sz = fn->con[i.arg[0].val].bits.i;
|
||||
if (sz < 0 || sz >= INT_MAX-15)
|
||||
err("invalid alloc size %"PRId64, sz);
|
||||
sz = (sz + 15) & -16;
|
||||
emit(OSAlloc, Kl, i.to, getcon(sz, fn), R);
|
||||
} else {
|
||||
/* r0 = (i.arg[0] + 15) & -16 */
|
||||
r0 = newtmp("isel", Kl, fn);
|
||||
|
@ -335,13 +334,13 @@ Emit:
|
|||
selcmp(i.arg, kc, fn);
|
||||
break;
|
||||
}
|
||||
diag("isel: non-exhaustive implementation");
|
||||
die("unknown instruction");
|
||||
}
|
||||
|
||||
while (i0 > curi && --i0)
|
||||
if (rslot(i0->arg[0], fn) != -1
|
||||
|| rslot(i0->arg[1], fn) != -1)
|
||||
diag("isel: usupported address argument");
|
||||
while (i0 > curi && --i0) {
|
||||
assert(rslot(i0->arg[0], fn) == -1);
|
||||
assert(rslot(i0->arg[1], fn) == -1);
|
||||
}
|
||||
}
|
||||
|
||||
static Ins *
|
||||
|
@ -733,7 +732,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
|
|||
}
|
||||
/* allocate return pad */
|
||||
ra = alloc(sizeof *ra);
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
aret.align -= 2;
|
||||
if (aret.align < 0)
|
||||
aret.align = 0;
|
||||
|
@ -822,7 +821,7 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
|
|||
} else
|
||||
classify(i0, i1, ac, OPar, 0);
|
||||
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
|
||||
s = 4;
|
||||
for (i=i0, a=ac; i<i1; i++, a++) {
|
||||
|
@ -856,7 +855,6 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
|
|||
for (i=i0, a=ac; i<i1; i++, a++) {
|
||||
if (i->op != OParc || a->inmem)
|
||||
continue;
|
||||
assert(NAlign == 3);
|
||||
for (al=0; a->align >> (al+2); al++)
|
||||
;
|
||||
r = TMP(a->cls[0]);
|
||||
|
@ -876,12 +874,12 @@ static int
|
|||
aref(Ref r, ANum *ai)
|
||||
{
|
||||
switch (rtype(r)) {
|
||||
default:
|
||||
diag("isel: aref defaulted");
|
||||
case RCon:
|
||||
return 2;
|
||||
case RTmp:
|
||||
return ai[r.val].n;
|
||||
default:
|
||||
die("constant or temporary expected");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -986,8 +984,6 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
|
|||
}
|
||||
}
|
||||
switch (ai[r.val].n) {
|
||||
default:
|
||||
diag("isel: amatch defaulted");
|
||||
case 3: /* s * i */
|
||||
if (!top) {
|
||||
a->index = al;
|
||||
|
@ -1023,6 +1019,8 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
|
|||
amatch(a, ar, ai, fn, 0);
|
||||
amatch(a, al, ai, fn, 0);
|
||||
break;
|
||||
default:
|
||||
die("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1092,15 +1090,15 @@ isel(Fn *fn)
|
|||
|
||||
/* assign slots to fast allocs */
|
||||
b = fn->start;
|
||||
assert(NAlign == 3 && "change n=4 and sz /= 4 below");
|
||||
/* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
|
||||
for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
|
||||
for (i=b->ins; i-b->ins < b->nins; i++)
|
||||
if (i->op == al) {
|
||||
if (rtype(i->arg[0]) != RCon)
|
||||
break;
|
||||
sz = fn->con[i->arg[0].val].bits.i;
|
||||
if (sz < 0 || sz >= INT_MAX-3)
|
||||
diag("isel: invalid alloc size");
|
||||
if (sz < 0 || sz >= INT_MAX-15)
|
||||
err("invalid alloc size %"PRId64, sz);
|
||||
sz = (sz + n-1) & -n;
|
||||
sz /= 4;
|
||||
fn->tmp[i->to.val].slot = fn->slot;
|
||||
|
|
2
mem.c
2
mem.c
|
@ -22,7 +22,7 @@ memopt(Fn *fn)
|
|||
for (i=b->ins; i-b->ins < b->nins; i++) {
|
||||
if (OAlloc > i->op || i->op > OAlloc1)
|
||||
continue;
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
assert(rtype(i->to) == RTmp);
|
||||
t = &fn->tmp[i->to.val];
|
||||
for (u=t->use; u != &t->use[t->nuse]; u++) {
|
||||
|
|
12
parse.c
12
parse.c
|
@ -159,18 +159,14 @@ static int ntyp;
|
|||
void
|
||||
err(char *s, ...)
|
||||
{
|
||||
char buf[100], *p, *end;
|
||||
va_list ap;
|
||||
|
||||
p = buf;
|
||||
end = buf + sizeof(buf);
|
||||
|
||||
va_start(ap, s);
|
||||
p += snprintf(p, end - p, "%s:%d: ", inpath, lnum);
|
||||
p += vsnprintf(p, end - p, s, ap);
|
||||
fprintf(stderr, "%s:%d: ", inpath, lnum);
|
||||
vfprintf(stderr, s, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
|
||||
diag(buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
4
rega.c
4
rega.c
|
@ -125,7 +125,7 @@ ralloc(RMap *m, int t)
|
|||
for (r=r0; r<r1; r++)
|
||||
if (!bshas(m->b, r))
|
||||
goto Found;
|
||||
diag("rega: no more regs");
|
||||
die("no more regs");
|
||||
}
|
||||
Found:
|
||||
radd(m, t, r);
|
||||
|
@ -170,7 +170,7 @@ pmadd(Ref src, Ref dst, int k)
|
|||
cpm = cpm * 2 + 16;
|
||||
pm = realloc(pm, cpm * sizeof pm[0]);
|
||||
if (!pm)
|
||||
diag("pmadd: out of memory");
|
||||
die("pmadd, out of memory");
|
||||
}
|
||||
pm[npm].src = src;
|
||||
pm[npm].dst = dst;
|
||||
|
|
10
spill.c
10
spill.c
|
@ -94,8 +94,7 @@ fillcost(Fn *fn)
|
|||
tmpuse(p->to, 0, 0, fn);
|
||||
for (a=0; a<p->narg; a++) {
|
||||
n = p->blk[a]->loop;
|
||||
assert(b->npred==p->narg &&
|
||||
"wrong cfg");
|
||||
assert(b->npred==p->narg && "wrong cfg");
|
||||
n /= b->npred;
|
||||
tmpuse(p->arg[a], 1, n, fn);
|
||||
}
|
||||
|
@ -146,11 +145,10 @@ slot(int t)
|
|||
{
|
||||
int s;
|
||||
|
||||
if (t < Tmp0)
|
||||
diag("spill: cannot spill register");
|
||||
assert(t >= Tmp0 && "cannot spill register");
|
||||
s = tmp[t].slot;
|
||||
if (s == -1) {
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
/* nice logic to pack stack slots
|
||||
* on demand, there can be only
|
||||
* one hole and slot4 points to it
|
||||
|
@ -491,7 +489,7 @@ spill(Fn *fn)
|
|||
}
|
||||
|
||||
/* align the locals to a 16 byte boundary */
|
||||
assert(NAlign == 3);
|
||||
/* specific to NAlign == 3 */
|
||||
slot8 += slot8 & 3;
|
||||
fn->slot += slot8;
|
||||
|
||||
|
|
6
ssa.c
6
ssa.c
|
@ -15,8 +15,6 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
|
|||
u->type = ty;
|
||||
u->bid = b->id;
|
||||
switch (ty) {
|
||||
default:
|
||||
diag("ssa: adduse defaulted");
|
||||
case UPhi:
|
||||
u->u.phi = va_arg(ap, Phi *);
|
||||
break;
|
||||
|
@ -25,6 +23,8 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
|
|||
break;
|
||||
case UJmp:
|
||||
break;
|
||||
default:
|
||||
die("unreachable");
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ renblk(Blk *b, Name **stk, Fn *fn)
|
|||
if ((t=fn->tmp[t].visit)) {
|
||||
m = p->narg++;
|
||||
if (m == NPred)
|
||||
diag("ssa: too many phi arguments");
|
||||
die("renblk, too many phi args");
|
||||
p->arg[m] = getstk(t, b, stk);
|
||||
p->blk[m] = b;
|
||||
}
|
||||
|
|
17
util.c
17
util.c
|
@ -1,4 +1,5 @@
|
|||
#include "all.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct Bitset Bitset;
|
||||
typedef struct Vec Vec;
|
||||
|
@ -28,9 +29,14 @@ static void **pool = ptr;
|
|||
static int nptr = 1;
|
||||
|
||||
void
|
||||
diag(char *s)
|
||||
die_(char *file, char *s, ...)
|
||||
{
|
||||
fputs(s, stderr);
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s: dying: ", file);
|
||||
va_start(ap, s);
|
||||
vfprintf(stderr, s, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
abort();
|
||||
}
|
||||
|
@ -42,7 +48,7 @@ emalloc(size_t n)
|
|||
|
||||
p = calloc(1, n);
|
||||
if (!p)
|
||||
diag("emalloc: out of memory");
|
||||
die("emalloc, out of memory");
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -95,7 +101,7 @@ void
|
|||
emit(int op, int k, Ref to, Ref arg0, Ref arg1)
|
||||
{
|
||||
if (curi == insb)
|
||||
diag("emit: too many instructions");
|
||||
die("emit, too many instructions");
|
||||
*--curi = (Ins){
|
||||
.op = op, .cls = k,
|
||||
.to = to, .arg = {arg0, arg1}
|
||||
|
@ -210,8 +216,7 @@ addcon(Con *c0, Con *c1)
|
|||
*c0 = *c1;
|
||||
else {
|
||||
if (c1->type == CAddr) {
|
||||
if (c0->type == CAddr)
|
||||
diag("addcon: adding two addresses");
|
||||
assert(c0->type != CAddr && "adding two addresses");
|
||||
c0->type = CAddr;
|
||||
strcpy(c0->label, c1->label);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue