mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-02-09 09:31:39 +00:00
Fix so the type of shift expressions depends only on the (promoted) type of their left operand.
This is as required by the C standards: the type of the right operand should not affect the result type. The following program demonstrates problems with the old behavior: #include <stdio.h> int main(void) { unsigned long ul; long l; unsigned u; int i; ul = 0x8000 << 1L; /* should be 0 */ printf("%lx\n", ul); l = -1 >> 1U; /* should be -1 */ printf("%ld\n", l); u = 0xFF10; l = 8; ul = u << l; /* should be 0x1000 */ printf("%lx\n", ul); l = -4; ul = 1; l = l >> ul; /* should be -2 */ printf("%ld\n", l); }
This commit is contained in:
parent
5618b2810e
commit
af48935d43
@ -1061,11 +1061,17 @@ var
|
||||
op1 := ord(op1 >= op2);
|
||||
ekind := intconst;
|
||||
end;
|
||||
ltltop : op1 := op1 << op2; {<<}
|
||||
gtgtop : if unsigned1 then {>>}
|
||||
ltltop : begin {<<}
|
||||
op1 := op1 << op2;
|
||||
ekind := kindLeft;
|
||||
end;
|
||||
gtgtop : begin {>>}
|
||||
if unsigned1 then
|
||||
op1 := lshr(op1,op2)
|
||||
else
|
||||
op1 := op1 >> op2;
|
||||
ekind := kindLeft;
|
||||
end;
|
||||
plusch : op1 := op1 + op2; {+}
|
||||
minusch : op1 := op1 - op2; {-}
|
||||
asteriskch : if unsigned then {*}
|
||||
@ -3199,9 +3205,16 @@ case tree^.token.kind of
|
||||
|
||||
ltltop: begin {<<}
|
||||
GenerateCode(tree^.left);
|
||||
et := UsualUnaryConversions;
|
||||
lType := expressionType;
|
||||
GenerateCode(tree^.right);
|
||||
case UsualBinaryConversions(lType) of
|
||||
if (expressionType^.kind <> scalarType)
|
||||
or not (expressionType^.baseType in
|
||||
[cgByte,cgUByte,cgWord,cgUWord,cgLong,cgULong]) then
|
||||
error(66);
|
||||
if expressionType^.baseType <> et then
|
||||
Gen2(pc_cnv, ord(expressionType^.baseType), ord(et));
|
||||
case et of
|
||||
cgByte,cgUByte,cgWord,cgUWord:
|
||||
Gen0(pc_shl);
|
||||
cgLong,cgULong:
|
||||
@ -3209,13 +3222,21 @@ case tree^.token.kind of
|
||||
otherwise:
|
||||
error(66);
|
||||
end; {case}
|
||||
expressionType := lType;
|
||||
end; {case ltltop}
|
||||
|
||||
gtgtop: begin {>>}
|
||||
GenerateCode(tree^.left);
|
||||
et := UsualUnaryConversions;
|
||||
lType := expressionType;
|
||||
GenerateCode(tree^.right);
|
||||
case UsualBinaryConversions(lType) of
|
||||
if (expressionType^.kind <> scalarType)
|
||||
or not (expressionType^.baseType in
|
||||
[cgByte,cgUByte,cgWord,cgUWord,cgLong,cgULong]) then
|
||||
error(66);
|
||||
if expressionType^.baseType <> et then
|
||||
Gen2(pc_cnv, ord(expressionType^.baseType), ord(et));
|
||||
case et of
|
||||
cgByte,cgWord:
|
||||
Gen0(pc_shr);
|
||||
cgUByte,cgUWord:
|
||||
@ -3227,6 +3248,7 @@ case tree^.token.kind of
|
||||
otherwise:
|
||||
error(66);
|
||||
end; {case}
|
||||
expressionType := lType;
|
||||
end; {case gtgtop}
|
||||
|
||||
plusch: begin {+}
|
||||
|
Loading…
x
Reference in New Issue
Block a user