commit 93e946da7e115b1cfbf118fdfac6e4c21c41a848
parent 85d2774262cd010da637bf06c3cb5c42abe6d000
Author: erai <erai@omiltem.net>
Date: Sat, 28 Sep 2024 10:14:16 -0400
add undefined evaluation order check
Diffstat:
M | cc0.c | | | 45 | +++++++++++++++++++++++++++++++++++++++++++++ |
M | cc1.c | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | kernel.c | | | 2 | +- |
M | sha256.c | | | 12 | ++++-------- |
M | sha512.c | | | 8 | ++++---- |
5 files changed, 116 insertions(+), 13 deletions(-)
diff --git a/cc0.c b/cc0.c
@@ -529,6 +529,7 @@ void( my_as_rex)(struct my_assembler* my_a,unsigned long my_op,unsigned long my_
void( my_assert)(unsigned long my_x,unsigned char* my_msg);
unsigned long( my_bind)(unsigned long my_fd,unsigned char* my_addr,unsigned long my_len);
void( my_bzero)(unsigned char* my_s,unsigned long my_size);
+unsigned long( my_call_check)(struct my_compiler* my_c,struct my_node* my_n);
void( my_cdie)(struct my_compiler* my_c,unsigned char* my_msg);
unsigned long( my_charset)(struct my_peg* my_c,unsigned char* my_s);
void( my_choice)(struct my_peg* my_c);
@@ -1448,6 +1449,47 @@ void( my_bzero)(unsigned char* my_s,unsigned long my_size){
(my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
}
}
+unsigned long( my_call_check)(struct my_compiler* my_c,struct my_node* my_n){
+ unsigned long my_result = 0;
+ unsigned long my_ret = 0;
+ (my_result)=(0UL);
+ if ((unsigned long)(!(my_n))) {
+ return my_result;
+ }
+ if ((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_CALL)))) {
+ (my_result)=((my_call_check)((my_c),((my_n)->my_a)));
+ (my_n)=((my_n)->my_b);
+ while (1) {
+ if ((unsigned long)(!(my_n))) {
+ break;
+ }
+ (my_ret)=((my_call_check)((my_c),((my_n)->my_a)));
+ if ((unsigned long)((my_result)&&(my_ret))) {
+ (my_cdie)((my_c),((unsigned char *)"multiple calls in call"));
+ }
+ (my_result)=((unsigned long)(((unsigned long)(my_result))|((unsigned long)(my_ret))));
+ (my_n)=((my_n)->my_b);
+ }
+ (my_result)=(1UL);
+ } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_BOR))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_BAND)))))) {
+ (my_result)=((my_call_check)((my_c),((my_n)->my_a)));
+ (my_result)=((unsigned long)(((unsigned long)(my_result))|((unsigned long)((my_call_check)((my_c),((my_n)->my_b))))));
+ } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_ASSIGN))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_INDEX))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_LT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_LE))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_GT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_GE))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_EQ))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NE))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_BNOT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_ADD))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_SUB))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_MUL))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_DIV))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_MOD))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_LSH))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_RSH))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_AND))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_OR))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_XOR)))))))))))))))))))))))))))))))))))))))) {
+ (my_result)=((my_call_check)((my_c),((my_n)->my_a)));
+ (my_ret)=((my_call_check)((my_c),((my_n)->my_b)));
+ if ((unsigned long)((my_result)&&(my_ret))) {
+ (my_cdie)((my_c),((unsigned char *)"multiple calls in expression"));
+ }
+ (my_result)=((unsigned long)(((unsigned long)(my_result))|((unsigned long)(my_ret))));
+ } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_REF))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_DEREF))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_POS))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NEG))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NOT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_CAST))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_DOT)))))))))))))))) {
+ (my_result)=((my_call_check)((my_c),((my_n)->my_a)));
+ } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_STR))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NUM))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_CHAR))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_IDENT))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_SIZEOF)))))))))))) {
+ } else {
+ (my_fdputd)((2UL),((my_n)->my_kind));
+ (my_die)(((unsigned char *)"invalid expr"));
+ }
+ return my_result;
+}
void( my_cdie)(struct my_compiler* my_c,unsigned char* my_msg){
(my_cshow_context)((my_c));
(my_fdputs)((2UL),((unsigned char *)"cdie: "));
@@ -2145,6 +2187,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
}
(my_no)=((my_mklabel)(((my_c)->my_as)));
if (((my_n)->my_a)->my_a) {
+ (my_call_check)((my_c),(((my_n)->my_a)->my_a));
(my_compile_expr)((my_c),(my_d),(((my_n)->my_a)->my_a),(1UL));
(my_emit_jz)(((my_c)->my_as),(my_no));
}
@@ -2183,6 +2226,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
if ((unsigned long)(((long)((((my_d)->my_func_type)->my_val)->my_kind))==((long)(my_TY_VOID)))) {
(my_cdie)((my_c),((unsigned char *)"returning a value in a void function"));
}
+ (my_call_check)((my_c),((my_n)->my_a));
(my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL));
(my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_d)->my_func_type)->my_val));
} else {
@@ -2202,6 +2246,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n
}
(my_emit_jmp)(((my_c)->my_as),((my_v)->my_goto_label));
} else if ((unsigned long)(((long)(my_kind))!=((long)(my_N_VARDECL)))) {
+ (my_call_check)((my_c),(my_n));
(my_compile_expr)((my_c),(my_d),(my_n),(1UL));
(my_emit_pop)(((my_c)->my_as),(1UL));
}
diff --git a/cc1.c b/cc1.c
@@ -1103,6 +1103,65 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
}
+call_check(c: *compiler, n: *node): int {
+ var result: int;
+ var ret: int;
+
+ result = 0;
+
+ if !n {
+ return result;
+ }
+
+ if n.kind == N_CALL {
+ result = call_check(c, n.a);
+ n = n.b;
+ loop {
+ if !n {
+ break;
+ }
+ ret = call_check(c, n.a);
+ if result && ret {
+ cdie(c, "multiple calls in call");
+ }
+ result = result | ret;
+ n = n.b;
+ }
+ result = 1;
+ } else if n.kind == N_BOR || n.kind == N_BAND {
+ // Side effects okay in both positions
+ result = call_check(c, n.a);
+ result = result | call_check(c, n.b);
+ } else if n.kind == N_ASSIGN || n.kind == N_INDEX || n.kind == N_LT
+ || n.kind == N_LE || n.kind == N_GT || n.kind == N_GE
+ || n.kind == N_EQ || n.kind == N_NE || n.kind == N_BNOT
+ || n.kind == N_ADD || n.kind == N_SUB || n.kind == N_MUL
+ || n.kind == N_DIV || n.kind == N_MOD || n.kind == N_LSH
+ || n.kind == N_RSH || n.kind == N_AND || n.kind == N_OR
+ || n.kind == N_XOR {
+ // Possible side effects in both positions
+ result = call_check(c, n.a);
+ ret = call_check(c, n.b);
+ if result && ret {
+ cdie(c, "multiple calls in expression");
+ }
+ result = result | ret;
+ } else if n.kind == N_REF || n.kind == N_DEREF || n.kind == N_POS
+ || n.kind == N_NEG || n.kind == N_NOT || n.kind == N_CAST
+ || n.kind == N_DOT {
+ // Possible side effect in the first position
+ result = call_check(c, n.a);
+ } else if n.kind == N_STR || n.kind == N_NUM || n.kind == N_CHAR
+ || n.kind == N_IDENT || n.kind == N_SIZEOF {
+ // No side effects
+ } else {
+ fdputd(2, n.kind);
+ die("invalid expr");
+ }
+
+ return result;
+}
+
// Compile a statement
compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
var no: *label;
@@ -1134,6 +1193,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
no = mklabel(c.as);
if (n.a.a) {
+ call_check(c, n.a.a);
compile_expr(c, d, n.a.a, 1);
emit_jz(c.as, no);
}
@@ -1174,6 +1234,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
if (d.func_type.val.kind == TY_VOID) {
cdie(c, "returning a value in a void function");
}
+ call_check(c, n.a);
compile_expr(c, d, n.a, 1);
unify(c, n.a.t, d.func_type.val);
} else {
@@ -1193,6 +1254,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
}
emit_jmp(c.as, v.goto_label);
} else if (kind != N_VARDECL) {
+ call_check(c, n);
compile_expr(c, d, n, 1);
emit_pop(c.as, 1);
}
diff --git a/kernel.c b/kernel.c
@@ -1241,7 +1241,7 @@ init_realtek(dev: *pcidev) {
var mac: int;
realtek_port = alloc():*realtek_port;
realtek_port.io = io;
- mac = ind(io) + (ind(io + 4) << 32);
+ mac = ind(io); mac = mac + (ind(io + 4) << 32);
realtek_port.mac = ((mac >> 40) & 0xff)
+ (((mac >> 32) & 0xff) << 8)
+ (((mac >> 24) & 0xff) << 16)
diff --git a/sha256.c b/sha256.c
@@ -65,19 +65,15 @@ sha256_round(ctx: *sha256_ctx, w: *int, k: int) {
var maj: int;
var w16: int;
- s1 = ror32(ctx.e, 6) ^ ror32(ctx.e, 11) ^ ror32(ctx.e, 25);
+ s1 = ror32(ctx.e, 6); s1 = s1 ^ ror32(ctx.e, 11); s1 = s1 ^ ror32(ctx.e, 25);
ch = (ctx.e & ctx.f) ^ ((~ctx.e) & ctx.g);
t1 = (ctx.h + s1 + ch + k + w[0]) & (-1 >> 32);
- s0 = ror32(ctx.a, 2) ^ ror32(ctx.a, 13) ^ ror32(ctx.a, 22);
+ s0 = ror32(ctx.a, 2); s0 = s0 ^ ror32(ctx.a, 13); s0 = s0 ^ ror32(ctx.a, 22);
maj = (ctx.a & ctx.b) ^ (ctx.a & ctx.c) ^ (ctx.b & ctx.c);
t2 = (s0 + maj) & (-1 >> 32);
- s0 = ror32(w[16 - 15], 7)
- ^ ror32(w[16 - 15], 18)
- ^ (w[16 - 15] >> 3);
- s1 = ror32(w[16 - 2], 17)
- ^ ror32(w[16 - 2], 19)
- ^ (w[16 - 2] >> 10);
+ s0 = ror32(w[16 - 15], 7); s0 = s0 ^ ror32(w[16 - 15], 18); s0 = s0 ^ (w[16 - 15] >> 3);
+ s1 = ror32(w[16 - 2], 17); s1 = s1 ^ ror32(w[16 - 2], 19); s1 = s1 ^ (w[16 - 2] >> 10);
w16 = (w[16 - 16] + s0 + w[16 - 7] + s1) & (-1 >> 32);
w[0] = w[1];
diff --git a/sha512.c b/sha512.c
@@ -62,10 +62,10 @@ sha512_round(r: *sha512_ctx, w: *int, k: int) {
var w16: int;
var i: int;
- s1 = ror64(r.e, 14) ^ ror64(r.e, 18) ^ ror64(r.e, 41);
+ s1 = ror64(r.e, 14); s1 = s1 ^ ror64(r.e, 18); s1 = s1 ^ ror64(r.e, 41);
ch = (r.e & r.f) ^ ((~r.e) & r.g);
t1 = r.h + s1 + ch + k + w[0];
- s0 = ror64(r.a, 28) ^ ror64(r.a, 34) ^ ror64(r.a, 39);
+ s0 = ror64(r.a, 28); s0 = s0 ^ ror64(r.a, 34); s0 = s0 ^ ror64(r.a, 39);
maj = (r.a & r.b) ^ (r.a & r.c) ^ (r.b & r.c);
t2 = s0 + maj;
@@ -78,8 +78,8 @@ sha512_round(r: *sha512_ctx, w: *int, k: int) {
r.b = r.a;
r.a = t1 + t2;
- s0 = ror64(w[1], 1) ^ ror64(w[1], 8) ^ (w[1] >> 7);
- s1 = ror64(w[14], 19) ^ ror64(w[14], 61) ^ (w[14] >> 6);
+ s0 = ror64(w[1], 1); s0 = s0 ^ ror64(w[1], 8); s0 = s0 ^ (w[1] >> 7);
+ s1 = ror64(w[14], 19); s1 = s1 ^ ror64(w[14], 61); s1 = s1 ^ (w[14] >> 6);
w16 = w[0] + s0 + w[9] + s1;
i = 0;