History

Riscv struct saving

While adding some testcases for attribute cleanup I found a bug in the riscv code. It modifies the sv->c.i in load_symofs. If a structure contains more then one element only the first is stored correctly. This only happens on a large stack frame. Fixed by saving/restoring sv->c.i.

herman ten brugge committed 1 year ago

Commit 7c23c481 parent 9670d103 files · +60 −0Browse files

Unified · Split

3 files
  1. riscv64-gen.c +4 −0
  2. tests/tests2/101_cleanup.c +50 −0
  3. tests/tests2/101_cleanup.expect +6 −0
riscv64-gen.c+4−0
@@ -233,6 +233,7 @@ ST_FUNC void load(int r, SValue *sv) · 232 unmodified lines
233233 int v = fr & VT_VALMASK;
234234 int rr = is_ireg(r) ? ireg(r) : freg(r);
235235 int fc = sv->c.i;
236+ int save_fc = fc;
236237 int bt = sv->type.t & VT_BTYPE;
237238 int align, size;
238239 if (fr & VT_LVAL) {
@@ -370,6 +371,7 @@ ST_FUNC void load(int r, SValue *sv) · 131 unmodified lines
370371 EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
371372 } else
372373 tcc_error("unimp: load(non-const)");
374+ sv->c.i = save_fc;
373375 }
374376
375377 ST_FUNC void store(int r, SValue *sv)
@@ -377,6 +379,7 @@ ST_FUNC void store(int r, SValue *sv) · 1 unmodified line
377379 int fr = sv->r & VT_VALMASK;
378380 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;
379381 int fc = sv->c.i;
382+ int save_fc = fc;
380383 int bt = sv->type.t & VT_BTYPE;
381384 int align, size = type_size(&sv->type, &align);
382385 assert(!is_float(bt) || is_freg(r) || bt == VT_LDOUBLE);
@@ -413,6 +416,7 @@ ST_FUNC void store(int r, SValue *sv) · 30 unmodified lines
413416 ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...
414417 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]
415418 ptrreg, rr, fc); // RR, fc(base)
419+ sv->c.i = save_fc;
416420 }
417421
418422 static void gcall_or_jmp(int docall)
tests/tests2/101_cleanup.c+50−0
@@ -5,6 +5,8 @@ typedef struct { int a; int b; int c; int d; int e; int f; int g; int h; } tstl; · 4 unmodified lines
55 typedef struct { int a; int b; int c; int d; } tsti;
66 typedef struct { double a; double b; } tstd;
77 typedef struct { long double a; } tstld;
8+typedef struct { int a; double b; } tstm;
9+typedef struct { float a; float b; float c; float d; } tstf;
810
911 void incr_glob_i(int *i)
1012 {
@@ -258,6 +260,44 @@ tstld test_cleanup5(void) { · 247 unmodified lines
258260 return n;
259261 }
260262
263+void my_cleanup6(tstm *p) {
264+ printf("%d %g\n", p->a, p->b);
265+ p->a = 90;
266+ p->b = 91.0;
267+}
268+
269+tstm test_cleanup6(void) {
270+ tstm __attribute__((cleanup(my_cleanup6))) n;
271+ n.a = 42;
272+ n.b = 43.0;
273+ return n;
274+}
275+
276+void my_cleanup7(tstf *p) {
277+ printf("%f %f %f %f\n", p->a, p->b, p->c, p->d);
278+ p->a = 0x90; p->b = 0x91; p->c = 0x92; p->d = 0x93;
279+}
280+
281+tstf test_cleanup7(void) {
282+ tstf __attribute__((cleanup(my_cleanup7))) n;
283+ n.a = 42; n.b = 43; n.c = 44; n.d = 45;
284+ return n;
285+}
286+
287+void my_cleanup8(int **p) {
288+ **p = 0x90;
289+}
290+
291+int test_cleanup8(void) {
292+ int n = 42;
293+ int __attribute__((cleanup(my_cleanup8))) *p = &n;
294+ return n;
295+}
296+
297+static void my_cleanupe(int *p) {
298+ *p = 0x90;
299+}
300+
261301 int main()
262302 {
263303 int i __attribute__ ((__cleanup__(check))) = 0, not_i;
@@ -267,6 +307,8 @@ int main() · 3 unmodified lines
267307 tsti ti;
268308 tstd td;
269309 tstld tld;
310+ tstm tm;
311+ tstf tf;
270312
271313 {
272314 __attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'o', o = 'a';
@@ -299,6 +341,14 @@ int main() · 26 unmodified lines
299341 printf("%g %g\n", td.a, td.b);
300342 tld = test_cleanup5();
301343 printf("%Lf\n", tld.a);
344+ tm = test_cleanup6();
345+ printf("%d %g\n", tm.a, tm.b);
346+ tf = test_cleanup7();
347+ printf("%f %f %f %f\n", tf.a, tf.b, tf.c, tf.d);
348+ printf("%d\n", test_cleanup8());
349+ printf("%d\n", ({
350+ int __attribute__ ((cleanup(my_cleanupe))) n = 42;
351+ n; }));
302352 return i;
303353 }
304354
tests/tests2/101_cleanup.expect+6−0
@@ -58,6 +58,12 @@ after break · 57 unmodified lines
5858 42 43
5959 42.000000
6060 42.000000
61+42 43
62+42 43
63+42.000000 43.000000 44.000000 45.000000
64+42.000000 43.000000 44.000000 45.000000
65+42
66+42
6167 ---- 0
6268 ---- 1
6369 str: plop

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t