Fix bug with 4-byte comparisons against globals in large memory model.

Long addressing was not being used to access the values, which could lead to mis-evaluation of comparisons against values in global structs, unions, or arrays, depending on the memory layout.

This could sometimes affect the c99desinit.c test, when run with large memory model and at least intermediate code peephole optimization. It could also affect this simpler test (depending on memory layout):

#pragma memorymodel 1
#pragma optimize 1
struct S {
        void *p;
} s =  {&s};
int main(void) {
        return s.p != &s; /* should be 0 */
}
This commit is contained in:
Stephen Heumann 2022-12-04 21:54:29 -06:00
parent 935bb6c04e
commit 2550081517
2 changed files with 13 additions and 3 deletions

14
Gen.pas
View File

@ -2048,9 +2048,17 @@ var
lab1 := GenLabel;
with op^ do begin
if opcode = pc_ldo then begin
GenNative(m_cmp_abs, absolute, q, lab, 0);
GenNative(m_bne, relative, lab1, nil, 0);
GenNative(m_cpx_abs, absolute, q+2, lab, 0);
if smallMemoryModel then begin
GenNative(m_cmp_abs, absolute, q, lab, 0);
GenNative(m_bne, relative, lab1, nil, 0);
GenNative(m_cpx_abs, absolute, q+2, lab, 0);
end {if}
else begin
GenNative(m_cmp_long, longabsolute, q, lab, 0);
GenNative(m_bne, relative, lab1, nil, 0);
GenImplied(m_txa);
GenNative(m_cmp_long, longabsolute, q+2, lab, 0);
end; {else}
end {if}
else begin
disp := LabelToDisp(r) + q;

View File

@ -2013,6 +2013,8 @@ int foo(int[42]);
223. Expressions of floating-point type could not be used in initializers for integer variables with static storage duration. This should be allowed, with a conversion performed as in the case of assignment.
224. Comparisons against four-byte values in global structures, unions, or arrays might not work correctly when using the large memory model.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.