Compare commits

...

2 Commits

Author SHA1 Message Date
Stephen Heumann 77e0b8fc59 Fix codegen error for some indirect accesses to 64-bit values.
The code was not properly adding in the offset of the 64-bit value from the pointed-to location, so the wrong memory location would be accessed. This affected indirect accesses to non-initial structure members, when used as operands to certain operations.

Here is an example showing the problem:

#include <stdio.h>

long long x = 123456;

struct S {
        long long a;
        long long b;
} s = {0, 123456};

int main(void) {
        struct S *sp = &s;

        if (sp->b != x) {
                puts("error");
        }
}
2024-04-03 21:04:47 -05:00
Stephen Heumann 50636bd28b Fix code generation for qualified struct or union function parameters.
They were not being properly recognized as structs/unions, so they were being passed by address rather than by value as they should be.

Here is an example affected by this:

struct S {int a,b,c,d;};

int f(struct S s) {
    return s.a + s.b + s.c + s.d;
}

int main(void) {
    const struct S s = {1,2,3,4};
    return f(s);
}
2024-04-01 20:37:51 -05:00
3 changed files with 16 additions and 5 deletions

View File

@ -3453,11 +3453,17 @@ var
while tp <> nil do begin while tp <> nil do begin
if tp^.middle <> nil then begin if tp^.middle <> nil then begin
GenerateCode(tp^.middle); GenerateCode(tp^.middle);
if expressionType^.kind in [structType,unionType] then begin if expressionType^.kind in [structType,unionType,definedType]
if expressionType^.size & $FFFF8000 <> 0 then then begin
Error(61); tType := expressionType;
Gen1t(pc_ldc, long(expressionType^.size).lsw, cgWord); while tType^.kind = definedType do
Gen0(pc_psh); tType := tType^.dType;
if tType^.kind in [structType,unionType] then begin
if tType^.size & $FFFF8000 <> 0 then
Error(61);
Gen1t(pc_ldc, long(tType^.size).lsw, cgWord);
Gen0(pc_psh);
end; {if}
end; {if} end; {if}
if fmt <> fmt_none then begin if fmt <> fmt_none then begin
new(tfp); new(tfp);

View File

@ -321,6 +321,7 @@ case op^.opcode of
loc := LabelToDisp(op^.left^.r) + op^.left^.q; loc := LabelToDisp(op^.left^.r) + op^.left^.q;
if (op^.left^.opcode <> pc_lod) or (loc > 255) then if (op^.left^.opcode <> pc_lod) or (loc > 255) then
Error(cge1); Error(cge1);
offset := offset + op^.q;
if offset = 0 then if offset = 0 then
GenNative(mop, direct, loc, nil, 0) GenNative(mop, direct, loc, nil, 0)
else begin else begin

View File

@ -1620,6 +1620,10 @@ If you use #pragma debug 0x0010 to enable stack check debug code, the compiler w
15. Native code peephole optimization might produce invalid code in some obscure circumstances where one element of a global or static array was decremented and then another element of the same array was accessed immediately thereafter. 15. Native code peephole optimization might produce invalid code in some obscure circumstances where one element of a global or static array was decremented and then another element of the same array was accessed immediately thereafter.
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.
-- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 --------------------- -- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 ---------------------
1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination. 1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination.