aboutsummaryrefslogtreecommitdiffhomepage
path: root/c/eval.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-13 17:34:15 +0100
committerlemon <lsof@mailbox.org>2025-12-13 17:39:08 +0100
commit6c7cdc537b7b341f9ca25a3e8b61de46c99840e7 (patch)
tree1cbbcee4cdace1c7f16d78ee46755d9cb825c754 /c/eval.c
parentfc7048a0c4c4b9647f032edfba74f7d7a62335e1 (diff)
c: handle more static eval edgecases for int -> ptr
sqlite3 was falling back to `((void*)&((char*)0)[X])` for INT_TO_PTR, which this handles now.
Diffstat (limited to 'c/eval.c')
-rw-r--r--c/eval.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/c/eval.c b/c/eval.c
index c9208b8..b6dad3a 100644
--- a/c/eval.c
+++ b/c/eval.c
@@ -177,12 +177,27 @@ isaddrconst(struct expr *ex)
return 1;
if (isglobsym(ex) && in_range(ex->ty.t, TYARRAY, TYFUNC))
return 1;
- if (ex->t == ESUB)
- return isglobsym(&ex->sub[0]) && isint(ex->sub[1].ty) && eval(&ex->sub[1], EVSTATICINI);
- if (ex->t == EADD) {
+ if (ex->t == ESUB) {
+ if (isaddrconst(&ex->sub[0]) && isint(ex->sub[1].ty) && eval(&ex->sub[1], EVSTATICINI)) {
+ assert(ex->sub[1].t == ENUMLIT);
+ if (eval(&ex->sub[0], EVSTATICINI) && ex->sub[0].t == ENUMLIT) {
+ /* handles (char *)10 - 5 */
+ ex->u = ex->sub[0].u - ex->sub[1].u * typesize(typechild(ex->sub[0].ty));
+ ex->t = ENUMLIT;
+ }
+ return 1;
+ }
+ } else if (ex->t == EADD) {
for (int swp = 0; swp < 2; ++swp)
- if (isglobsym(&ex->sub[swp]) && isint(ex->sub[swp^1].ty) && eval(&ex->sub[swp^1], EVSTATICINI))
+ if (isaddrconst(&ex->sub[swp]) && isint(ex->sub[swp^1].ty) && eval(&ex->sub[swp^1], EVSTATICINI)) {
+ assert(ex->sub[swp^1].t == ENUMLIT);
+ if (eval(&ex->sub[swp], EVSTATICINI) && ex->sub[swp].t == ENUMLIT) {
+ /* handles (char *)1234 + 5678 */
+ ex->u = ex->sub[swp].u + ex->sub[swp^1].u * typesize(typechild(ex->sub[swp].ty));
+ ex->t = ENUMLIT;
+ }
return 1;
+ }
}
return 0;
}