diff options
| author | 2025-12-13 17:34:15 +0100 | |
|---|---|---|
| committer | 2025-12-13 17:39:08 +0100 | |
| commit | 6c7cdc537b7b341f9ca25a3e8b61de46c99840e7 (patch) | |
| tree | 1cbbcee4cdace1c7f16d78ee46755d9cb825c754 | |
| parent | fc7048a0c4c4b9647f032edfba74f7d7a62335e1 (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.
| -rw-r--r-- | c/c.c | 2 | ||||
| -rw-r--r-- | c/eval.c | 23 | ||||
| -rw-r--r-- | test/15-reloc.c | 9 |
3 files changed, 29 insertions, 5 deletions
@@ -788,7 +788,7 @@ ppostfixopers(struct comp *cm, struct expr *ex) rhs = commaexpr(cm); span = ex->span; if (!joinspan(&span.ex, tk.span.ex) || !joinspan(&span.ex, ex->span.ex) - || (peek(cm, &tk2), !joinspan(&span.ex, tk.span.ex))) + || (peek(cm, &tk), !joinspan(&span.ex, tk.span.ex))) span = tk.span; expect(cm, ']', NULL); @@ -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; } diff --git a/test/15-reloc.c b/test/15-reloc.c index cd91fd0..713e98d 100644 --- a/test/15-reloc.c +++ b/test/15-reloc.c @@ -3,6 +3,7 @@ 1.3 5 ok +0x55, 0x6, 5 */ const void *const relro = &relro; @@ -22,9 +23,17 @@ int (*(getputs(void)))(const char *) { return t; } +static char *int2ptr[] = { + (void *)&*((char*)0 + 0x55), + (void *)&((short*)0)[0x3], + (void *)&*((char*)7 - 2), +}; + #include <stdio.h> +#include <stdint.h> int main() { printf("%g\n", get_value(2)); printf("%d\n", ou(2)); getputs()("ok"); + printf("%p, %p, %d\n", int2ptr[0], int2ptr[1], (int)(intptr_t)int2ptr[2]); } |