Mercurial > hg > tinycc
changeset 437:3f48bed56ab4
Fix bug in ||, &&, ! (save registers through jumps), grischka-2005-09-25 case_2
This saves registers through jumps with ||, &&, and !.
This patch was originally posted in grischka's 2005-09-25 email as
"required fix" case_2 to compile gcc 2.95. It was tweaked by
David A. Wheeler to merge the test case into the standard tcc test suite.
The original test case only tested || (case 2.1) and ! (case 2.2);
Wheeler added the test cases for && (which happens to completely crash
the unpatched compiler at compiler time - pretty solid evidence of
a problem in the unpatched program!).
author | Rob Landley <rob@landley.net> |
---|---|
date | Thu, 03 May 2007 13:08:53 -0400 |
parents | 91152e505b77 |
children | 31171653b1ee |
files | tcc.c tests/tcctest.c |
diffstat | 2 files changed, 28 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/tcc.c Thu May 03 12:10:26 2007 -0400 +++ b/tcc.c Thu May 03 13:08:53 2007 -0400 @@ -6486,8 +6486,10 @@ vtop->c.i = !vtop->c.i; else if ((vtop->r & VT_VALMASK) == VT_CMP) vtop->c.i = vtop->c.i ^ 1; - else + else { + save_regs(1); vseti(VT_JMP, gtst(1, 0)); + } break; case '~': next(); @@ -6900,6 +6902,7 @@ expr_or(); if (tok == TOK_LAND) { t = 0; + save_regs(1); for(;;) { t = gtst(1, t); if (tok != TOK_LAND) { @@ -6919,6 +6922,7 @@ expr_land(); if (tok == TOK_LOR) { t = 0; + save_regs(1); for(;;) { t = gtst(0, t); if (tok != TOK_LOR) {
--- a/tests/tcctest.c Thu May 03 12:10:26 2007 -0400 +++ b/tests/tcctest.c Thu May 03 13:08:53 2007 -0400 @@ -646,6 +646,29 @@ isid('g'), isid('T'), isid('(')); + + { + /* Check that tcc saves registers before a conditional jump */ + /* Addresses bug "grischka case_2" */ + struct test_str { int a, b, c; }; + struct test_str t1 = {0,0,0}; + struct test_str t2 = {1,1,1}; + struct test_str *p1 = &t1; + struct test_str *p2 = &t2; + int f = 0; + int g = 0; + + p1->b = f==0 || isid(0); + printf("case_2.1: Expect 0 1 0 -> %d %d %d\n", p1->a, p1->b, p1->c); + p1->c = !f || isid(0); + printf("case_2.2: Expect 0 1 1 -> %d %d %d\n", p1->a, p1->b, p1->c); + + /* This will crash old versions of tcc during compilation: */ + p2->b = (f==1) && isid(0); + printf("case_2.1AND: Expect 0 1 0 -> %d %d %d\n", p2->a, p2->b, p2->c); + p2->b = (!(f==1)) && isid(0); + printf("case_2.2AND: Expect 0 1 0 -> %d %d %d\n", p2->a, p2->b, p2->c); + } } int isid(int c)