Determine the type to use for computing a >>= or <<= operation based only on the left operand.

Also, fix a case where an uninitialized value could be used, potentially resulting in errors not being reported (although I haven’t seen that in practice).

This fixes problems where >>= operations might not use an arithmetic shift in certain cases where they should, as in the below program:

#include <stdio.h>
int main (void)
{
    int i;
    unsigned u;
    long l;
    unsigned long ul;

    i = -1;
    u = 1;
    i >>= u;
    printf("%i\n", i); /* should be -1 */

    l = -1;
    ul = 3;
    l >>= ul;
    printf("%li\n", l); /* should be -1 */
}
This commit is contained in:
Stephen Heumann 2016-11-21 00:25:58 -06:00
parent 67a29304a7
commit 896c60d18c
1 changed files with 12 additions and 1 deletions

View File

@ -2963,8 +2963,19 @@ case tree^.token.kind of
else
kind := lType^.kind;
GenerateCode(tree^.right);
if tree^.token.kind in [gtgteqop,ltlteqop] then
if kind = scalarType then
if expressionType^.kind = scalarType then begin
et := UsualUnaryConversions;
if et <> Unary(ltype^.baseType) then begin
Gen2(pc_cnv, et, ord(Unary(ltype^.baseType)));
expressionType := lType;
end; {if}
end; {if}
if kind <> pointerType then
et := UsualBinaryConversions(lType);
et := UsualBinaryConversions(lType)
else
et := ccPointer;
case tree^.token.kind of
pluseqop: