aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/all.h1
-rw-r--r--bootstrap/cgen.c8
-rw-r--r--bootstrap/parse.c9
-rw-r--r--bootstrap/types.c13
4 files changed, 25 insertions, 6 deletions
diff --git a/bootstrap/all.h b/bootstrap/all.h
index f8eb769..ceb9841 100644
--- a/bootstrap/all.h
+++ b/bootstrap/all.h
@@ -585,6 +585,7 @@ void visittypes(void (*visitor)(const struct type *, void *), void *arg);
const struct type *constify(const struct type *ty);
const struct type *unconstify(const struct type *ty);
const struct type *constifychild(const struct type *ty);
+const struct type *unconstifychild(const struct type *ty);
int numtype2rank(const struct type *a);
const struct type * rank2numtype(int r);
bool isnumtype(const struct type *a);
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c
index b0cfd92..7519982 100644
--- a/bootstrap/cgen.c
+++ b/bootstrap/cgen.c
@@ -541,7 +541,7 @@ liftdecl(struct decl *decl) {
static int id;
switch (decl->t) {
case Dfn:
- if (decl->fn.body || (decl->container && !decl->externp)) {
+ if ((decl->fn.body || (decl->container && !decl->externp)) && !*decl->_cname) {
if (decl->container)
*decl->_cname = xasprintf("__m%s_%s%d", decl->container->agg.name, decl->fn.name, decl->fn.id);
else
@@ -710,6 +710,12 @@ defctype(const struct type *ty, void *_) {
}
break;
case TYslice:
+ if (ty->child->konst) {
+ const struct type *ty2 = unconstifychild(ty);
+ defctype(ty2, NULL);
+ *cname = (char *)ty2->_cname;
+ return;
+ }
defctype(ty->child, NULL);
*cname = xasprintf("__ty%d", id++);
pri("typedef struct { %t *ptr; size_t len; } %s;\n",
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index 7c31ce1..7ff52bf 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -1178,7 +1178,7 @@ pexprimary(struct parser *P) {
ex = parsearrini(P, P->targty);
} else if (lexmatch(P, &tok, TKkw_sizeof)) {
ex.t = Eintlit;
- ex.ty = ty_usize;
+ ex.ty = ty_isize;
if (lexmatch(P, &tok, '(')) {
struct expr exp = parseexpr(P);
ex.i = exp.ty->size;
@@ -1320,13 +1320,13 @@ pexpostfix(struct parser *P) {
if (ty->t == TYarr) {
assert(ty->length >= 0);
ex.t = Eintlit;
- ex.ty = ty->konst ? constify(ty_usize) : ty_usize;
+ ex.ty = ty->konst ? constify(ty_isize) : ty_isize;
ex.span = tok.span;
ex.i = ty->length;
} else if (ty->t == TYslice) {
ex.child = exprdup(ex);
ex.t = Elen;
- ex.ty = ty->konst ? constify(ty_usize) : ty_usize;
+ ex.ty = ty->konst ? constify(ty_isize) : ty_isize;
ex.span = tok.span;
} else {
fatal(P, ex.span, "invalid operand to `.#len' (%t)", ex.ty);
@@ -1654,6 +1654,7 @@ pexcmp(struct parser *P) {
ex = pexbitarith(P);
if (P->used_targty) return ex;
if (matchcmpop(P, &tok)) {
+ P->targty = ex.ty;
struct expr rhs = pexbitarith(P);
if (!typeof2(ex.ty, rhs.ty))
fatal(P, tok.span, "incompatible operands %t and %t to binary operator %T",
@@ -1713,7 +1714,7 @@ pexcond(struct parser *P) {
struct expr ex3;
const struct type *ty;
- if (ex.ty->t != TYbool)
+ if (ex.ty->t != TYbool && ex.ty->t != TYptr)
fatal(P, ex.span, "invalid test operand %t to conditional operator", ex.ty);
lexexpect(P, ':');
diff --git a/bootstrap/types.c b/bootstrap/types.c
index 66ae840..37977ea 100644
--- a/bootstrap/types.c
+++ b/bootstrap/types.c
@@ -301,6 +301,16 @@ constifychild(const struct type *ty) {
return interntype(ty2);
}
+const struct type *
+unconstifychild(const struct type *ty) {
+ struct type ty2 = *ty;
+ const struct type *child = unconstify(ty->child);
+ if (child == ty->child)
+ return ty;
+ ty2.child = child;
+ return interntype(ty2);
+}
+
static const struct type *
arraydecay(const struct type *ty) {
struct type ty2 = *ty;
@@ -367,7 +377,7 @@ typeof2(const struct type *a, const struct type *b) {
b = arraydecay(b);
if (a->t == TYarr && b->t == TYptr)
a = arraydecay(a);
- if (a->t == TYptr && b->t == TYptr) {
+ if (a->t == b->t && (a->t == TYptr || a->t == TYslice)) {
bool akonst = a->child->konst,
bkonst = b->child->konst;
const struct type *uac = unconstify(a->child),
@@ -396,6 +406,7 @@ typeof2(const struct type *a, const struct type *b) {
}
}
+
return NULL;
}