Previously in order to perform a ll+ll operation tcc was trying to 'lexpand' PTR in gen_opl which did not work well. The case: int printf(const char *, ...); char t[] = "012345678"; int main(void) { char *data = t; unsigned long long r = 4; unsigned a = 5; unsigned long long b = 12; *(unsigned*)(data + r) += a - b; printf("data %s\n", data); return 0; }
Unified · Split
| @@ -133,6 +133,21 @@ ST_FUNC void check_vstack(void) · 132 unmodified lines | ||
| 133 | 133 | tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | +/* ------------------------------------------------------------------------- */ | |
| 137 | +/* vstack debugging aid */ | |
| 138 | + | |
| 139 | +#if 0 | |
| 140 | +void pv (const char *lbl, int a, int b) | |
| 141 | +{ | |
| 142 | + int i; | |
| 143 | + for (i = a; i < a + b; ++i) { | |
| 144 | + SValue *p = &vtop[-i]; | |
| 145 | + printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n", | |
| 146 | + lbl, i, p->type.t, p->r, p->r2, (int)p->c.i); | |
| 147 | + } | |
| 148 | +} | |
| 149 | +#endif | |
| 150 | + | |
| 136 | 151 | /* ------------------------------------------------------------------------- */ |
| 137 | 152 | /* symbol allocator */ |
| 138 | 153 | static Sym *__sym_malloc(void) |
| @@ -1212,6 +1227,7 @@ static void gen_opl(int op) · 1073 unmodified lines | ||
| 1212 | 1227 | case '*': |
| 1213 | 1228 | case '+': |
| 1214 | 1229 | case '-': |
| 1230 | + //pv("gen_opl A",0,2); | |
| 1215 | 1231 | t = vtop->type.t; |
| 1216 | 1232 | vswap(); |
| 1217 | 1233 | lexpand(); |
| @@ -1226,6 +1242,7 @@ static void gen_opl(int op) · 8 unmodified lines | ||
| 1226 | 1242 | vtop[-3] = tmp; |
| 1227 | 1243 | vswap(); |
| 1228 | 1244 | /* stack: H1 H2 L1 L2 */ |
| 1245 | + //pv("gen_opl B",0,4); | |
| 1229 | 1246 | if (op == '*') { |
| 1230 | 1247 | vpushv(vtop - 1); |
| 1231 | 1248 | vpushv(vtop - 1); |
| @@ -1760,6 +1777,11 @@ ST_FUNC void gen_op(int op) · 528 unmodified lines | ||
| 1760 | 1777 | vswap(); |
| 1761 | 1778 | swap(&t1, &t2); |
| 1762 | 1779 | } |
| 1780 | +#if PTR_SIZE == 4 | |
| 1781 | + if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG) | |
| 1782 | + /* XXX: truncate here because gen_opl can't handle ptr + long long */ | |
| 1783 | + gen_cast(&int_type); | |
| 1784 | +#endif | |
| 1763 | 1785 | type1 = vtop[-1].type; |
| 1764 | 1786 | type1.t &= ~VT_ARRAY; |
| 1765 | 1787 | if (vtop[-1].type.t & VT_VLA) |
| @@ -0,0 +1,15 @@ | ||
| 1 | +int printf(const char *, ...); | |
| 2 | +char t[] = "012345678"; | |
| 3 | + | |
| 4 | +int main(void) | |
| 5 | +{ | |
| 6 | + char *data = t; | |
| 7 | + unsigned long long r = 4; | |
| 8 | + unsigned a = 5; | |
| 9 | + unsigned long long b = 12; | |
| 10 | + | |
| 11 | + *(unsigned*)(data + r) += a - b; | |
| 12 | + | |
| 13 | + printf("data = \"%s\"\n", data); | |
| 14 | + return 0; | |
| 15 | +} | |
| @@ -0,0 +1 @@ | ||
| 1 | +data = "0123-5678" | |