aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c/c.c2
-rw-r--r--c/eval.c23
-rw-r--r--test/15-reloc.c9
3 files changed, 29 insertions, 5 deletions
diff --git a/c/c.c b/c/c.c
index d79439a..5ff2041 100644
--- a/c/c.c
+++ b/c/c.c
@@ -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);
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;
}
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]);
}