From 6b7414384f6bd8963c292056111232cce81dfaa1 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Wed, 10 Apr 2024 20:49:17 -0500 Subject: [PATCH] Fix code generation bug for indirect load/store of 64-bit values. The issue was that if a 64-bit value was being loaded via one pointer and stored via another, the load and store parts could both be using y for their indexing, but they would clash with each other, potentially leading to loads coming from the wrong place. Here are some examples that illustrate the problem: /* example 1 */ int main(void) { struct { char c[16]; long long x; } s = {.x = 0x1234567890abcdef}, *sp = &s; long long ll, *llp = ≪ *llp = sp->x; return ll != s.x; // should return 0 } /* example 2 */ int main(void) { struct { char c[16]; long long x; } s = {.x = 0x1234567890abcdef}, *sp = &s; long long ll, *llp = ≪ unsigned i = 0; *llp = sp[i].x; return ll != s.x; // should return 0 } /* example 3 */ int main(void) { long long x[2] = {0, 0x1234567890abcdef}, *xp = x; long long ll, *llp = ≪ unsigned i = 1; *llp = xp[i]; return ll != x[1]; // should return 0 } --- Gen.pas | 105 ++++++++++++++++++------------------------------------- cc.notes | 2 +- 2 files changed, 35 insertions(+), 72 deletions(-) diff --git a/Gen.pas b/Gen.pas index 82f5c2f..4bdf47d 100644 --- a/Gen.pas +++ b/Gen.pas @@ -3283,81 +3283,44 @@ case optype of gQuad := lQuad; gQuad.where := gQuad.preference; {unless overridden later} if gLong.where = inPointer then begin - if q = 0 then begin - if gLong.fixedDisp then begin - GenNative(m_ldy_imm, immediate, 6, nil, 0); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(6); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(4); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(2); - GenNative(m_lda_indl, direct, gLong.disp, nil, 0); - StoreWordOfQuad(0); - end {if} + if gLong.fixedDisp then begin + GenNative(m_ldy_imm, immediate, q+6, nil, 0); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + StoreWordOfQuad(6); + GenNative(m_ldy_imm, immediate, q+4, nil, 0); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + StoreWordOfQuad(4); + GenNative(m_ldy_imm, immediate, q+2, nil, 0); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + StoreWordOfQuad(2); + if q = 0 then + GenNative(m_lda_indl, direct, gLong.disp, nil, 0) else begin - GenImplied(m_tya); - GenImplied(m_clc); - GenNative(m_adc_imm, immediate, 6, nil, 0); - GenImplied(m_tay); + GenNative(m_ldy_imm, immediate, q, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(6); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(4); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(2); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(0); end; {else} - end {if q = 0} + StoreWordOfQuad(0); + end {if} else begin - if gLong.fixedDisp then begin - GenNative(m_ldy_imm, immediate, q+6, nil, 0); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(6); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(4); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(2); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(0); - end {if} - else begin - GenImplied(m_tya); - GenImplied(m_clc); - GenNative(m_adc_imm, immediate, q+6, nil, 0); - GenImplied(m_tay); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(6); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(4); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(2); - GenImplied(m_dey); - GenImplied(m_dey); - GenNative(m_lda_indly, direct, gLong.disp, nil, 0); - StoreWordOfQuad(0); - end; {else} + gQuad.where := onStack; + GenImplied(m_tya); + GenImplied(m_clc); + GenNative(m_adc_imm, immediate, q+6, nil, 0); + GenImplied(m_tay); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + GenImplied(m_pha); + GenImplied(m_dey); + GenImplied(m_dey); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + GenImplied(m_pha); + GenImplied(m_dey); + GenImplied(m_dey); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + GenImplied(m_pha); + GenImplied(m_dey); + GenImplied(m_dey); + GenNative(m_lda_indly, direct, gLong.disp, nil, 0); + GenImplied(m_pha); end; {else} end {if glong.where = inPointer} else if gLong.where = localAddress then begin diff --git a/cc.notes b/cc.notes index d82ea86..bab12d2 100644 --- a/cc.notes +++ b/cc.notes @@ -1622,7 +1622,7 @@ If you use #pragma debug 0x0010 to enable stack check debug code, the compiler w 16. When an expression of const- or volatile-qualified struct or union type was passed as a function parameter, incorrect code would be generated. This could lead to incorrect program behavior or crashes. -17. Incorrect code could sometimes be generated if a long long or unsigned long long value was a non-initial member of a structure, and it was accessed through a pointer to the structure and used as an operand of certain arithmetic, bitwise, or comparison operators. +17. Incorrect code could be generated in certain circumstances where a long long or unsigned long long member of a structure or array was accessed via a pointer. -- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 ---------------------