Prevent errors in loop invariant removal from trying to remove only the left subexpression of a comma operator.

Such subexpressions are not of the right form to work with the existing code, because they do not generate a value for use in the enclosing expression. For now, the code has been changed to simply not remove the subexpression in these cases. Alternative code could be written to make it work, but that might be more trouble than it's worth.

Here's an example that shows the problem (derived from a csmith-generated test case):

#pragma optimize 32+1 /* also had a problem with just 32 */
int main(void) {
    int x, y=10; /* also had problems if x was global */
    do {
        x=42, y-=1;
    } while (y);
    return x+y;
}
This commit is contained in:
Stephen Heumann 2018-03-25 14:01:14 -05:00
parent 237af41e90
commit 9b08d4337a
1 changed files with 4 additions and 2 deletions

View File

@ -4347,7 +4347,9 @@ var
optype: baseTypeEnum; {type of the temp variable}
begin {Remove}
if (op^.left <> nil) or (op^.right <> nil) then begin
if op^.opcode in [pc_pop,pc_str,pc_sro,pc_sto,pc_sbf] then
{do nothing for now - would need special code to move these}
else if (op^.left <> nil) or (op^.right <> nil) then begin
optype := TypeOf(op); {create a temp label}
loc := pointer(Calloc(sizeof(intermediate_code)));
loc^.opcode := dc_loc;
@ -4375,7 +4377,7 @@ var
str^.left := op2;
str^.next := loc^.next; {insert the store in the basic block}
loc^.next := str;
end; {if}
end; {else if}
done := true;
end; {Remove}