Make || and && operators in constant expressions yield results of type int.

Previously the result type was based on the operand types (using the arithmetic conversions), which is incorrect. The following program illustrates the issue:

#include <stdio.h>
int main(void)
{
    /* should print "1 0 2 2" */
    printf("%i %i %lu %lu\n", 0L || 2, 0.0 && 2,
           sizeof(1L || 5), sizeof(1.0 && 2.5));
}
This commit is contained in:
Stephen Heumann 2016-12-20 22:40:24 -06:00
parent 40bed0a93e
commit 280f67e846
1 changed files with 16 additions and 8 deletions

View File

@ -1039,10 +1039,14 @@ var
dispose(op^.left);
op^.left := nil;
case op^.token.kind of
barbarop : {||}
op1 := ord((op1 <> 0) or (op2 <> 0));
andandop : {&&}
op1 := ord((op1 <> 0) and (op2 <> 0));
barbarop : begin {||}
op1 := ord((op1 <> 0) or (op2 <> 0));
ekind := intconst;
end;
andandop : begin {&&}
op1 := ord((op1 <> 0) and (op2 <> 0));
ekind := intconst;
end;
carotch : op1 := op1 ! op2; {^}
barch : op1 := op1 | op2; {|}
andch : op1 := op1 & op2; {&}
@ -1147,10 +1151,14 @@ var
dispose(op^.left);
op^.left := nil;
case op^.token.kind of
barbarop : {||}
rop1 := ord((rop1 <> 0.0) or (rop2 <> 0.0));
andandop : {&&}
rop1 := ord((rop1 <> 0.0) and (rop2 <> 0.0));
barbarop : begin {||}
op1 := ord((rop1 <> 0.0) or (rop2 <> 0.0));
ekind := intconst;
end;
andandop : begin {&&}
op1 := ord((rop1 <> 0.0) and (rop2 <> 0.0));
ekind := intconst;
end;
eqeqop : begin {==}
op1 := ord(rop1 = rop2);
ekind := intconst;