aboutsummaryrefslogtreecommitdiff
path: root/tests/tcctest.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2012-04-16 02:52:15 +0200
committerMichael Matz <matz@suse.de>2012-04-18 20:57:14 +0200
commit9ca9c82ff8a4001299a4b9666d85352f5806d565 (patch)
treecccd695d9db32bcba58c89a614eee9f5564371a5 /tests/tcctest.c
parent718fd591fa93ff254a9ca68a0ad2ff8a55756489 (diff)
downloadtinycc-9ca9c82ff8a4001299a4b9666d85352f5806d565.tar.gz
tinycc-9ca9c82ff8a4001299a4b9666d85352f5806d565.tar.bz2
Fix comparing comparisons
Sometimes the result of a comparison is not directly used in a jump, but in arithmetic or further comparisons. If those further things do a vswap() with the VT_CMP as current top, and then generate instructions for the new top, this most probably destroys the flags (e.g. if it's a bitfield load like in the example). vswap() must do the same like vsetc() and not allow VT_CMP vtops to be moved down.
Diffstat (limited to 'tests/tcctest.c')
-rw-r--r--tests/tcctest.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 9598fa4..7772f89 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -86,6 +86,7 @@ void asm_test(void);
void builtin_test(void);
void weak_test(void);
void global_data_test(void);
+void cmp_comparison_test(void);
int fib(int n);
void num(int n);
@@ -592,6 +593,7 @@ int main(int argc, char **argv)
builtin_test();
weak_test();
global_data_test();
+ cmp_comparison_test();
return 0;
}
@@ -2562,3 +2564,31 @@ void global_data_test (void)
global_data_callit (0);
printf ("%d\n", global_data.a[0]);
}
+
+struct cmpcmpS
+{
+ unsigned char fill : 3;
+ unsigned char b1 : 1;
+ unsigned char b2 : 1;
+ unsigned char fill2 : 3;
+};
+
+int glob1, glob2, glob3;
+
+void compare_comparisons (struct cmpcmpS *s)
+{
+ if (s->b1 != (glob1 == glob2)
+ || (s->b2 != (glob1 == glob3)))
+ printf ("comparing comparisons broken\n");
+}
+
+void cmp_comparison_test(void)
+{
+ struct cmpcmpS s;
+ s.b1 = 1;
+ glob1 = 42; glob2 = 42;
+ s.b2 = 0;
+ glob3 = 43;
+ compare_comparisons (&s);
+ return 0;
+}