[cfe-dev] LHS of a << operand being implicitly cast to int

Farzad Sadeghi via cfe-dev cfe-dev at lists.llvm.org
Wed Jan 11 02:36:11 PST 2017


i have the following sample code:

short unsigned int port = 0x005aU;
unsigned char portchar = 0x005aU;
short unsigned int resultshort;

resultshort = port << 4U;
resultshort = portchar << 4U;

resultshort = port << 4U;
resultshort = portchar << 4U;
resultshort = (unsigned short int)(portchar << 4U);

Here's the AST dump for the last three lines:
-BinaryOperator 0x557ff78 <line:337:3, col:25> 'unsigned short' '='
|   | |-DeclRefExpr 0x557fe98 <col:3> 'unsigned short' lvalue Var
0x557fbb8 'resultshort' 'unsigned short'
|   | `-ImplicitCastExpr 0x557ff60 <col:17, col:25> 'unsigned short'
<IntegralCast>
|   |   `-BinaryOperator 0x557ff38 <col:17, col:25> 'int' '<<'
|   |     |-ImplicitCastExpr 0x557ff20 <col:17> 'int' <IntegralCast>
|   |     | `-ImplicitCastExpr 0x557ff08 <col:17> 'unsigned short'
<LValueToRValue>
|   |     |   `-DeclRefExpr 0x557fec0 <col:17> 'unsigned short' lvalue
Var 0x557fa28 'port' 'unsigned short'
|   |     `-IntegerLiteral 0x557fee8 <col:25> 'unsigned int' 4

|-BinaryOperator 0x5580080 <line:338:3, col:29> 'unsigned short' '='
|   | |-DeclRefExpr 0x557ffa0 <col:3> 'unsigned short' lvalue Var
0x557fbb8 'resultshort' 'unsigned short'
|   | `-ImplicitCastExpr 0x5580068 <col:17, col:29> 'unsigned short'
<IntegralCast>
|   |   `-BinaryOperator 0x5580040 <col:17, col:29> 'int' '<<'
|   |     |-ImplicitCastExpr 0x5580028 <col:17> 'int' <IntegralCast>
|   |     | `-ImplicitCastExpr 0x5580010 <col:17> 'unsigned char'
<LValueToRValue>
|   |     |   `-DeclRefExpr 0x557ffc8 <col:17> 'unsigned char' lvalue
Var 0x557faf0 'portchar' 'unsigned char'
|   |     `-IntegerLiteral 0x557fff0 <col:29> 'unsigned int' 4

|-BinaryOperator 0x5580620 <line:339:3, col:52> 'unsigned short' '='
|   | |-DeclRefExpr 0x55800a8 <col:3> 'unsigned short' lvalue Var
0x557fbb8 'resultshort' 'unsigned short'
|   | `-CStyleCastExpr 0x55805f8 <col:17, col:52> 'unsigned short'
<IntegralCast>
|   |   `-ParenExpr 0x55805d8 <col:37, col:52> 'int'
|   |     `-BinaryOperator 0x5580148 <col:38, col:50> 'int' '<<'
|   |       |-ImplicitCastExpr 0x5580130 <col:38> 'int' <IntegralCast>
|   |       | `-ImplicitCastExpr 0x5580118 <col:38> 'unsigned char'
<LValueToRValue>
|   |       |   `-DeclRefExpr 0x55800d0 <col:38> 'unsigned char'
lvalue Var 0x557faf0 'portchar' 'unsigned char'
|   |       `-IntegerLiteral 0x55800f8 <col:50> 'unsigned int' 4

switching "4U" with "const unsinged char constuchar=4U;" will still
result in the same thing, the RHS and LHS of a "<<" operator being
implicitly cast to int(signed and wider than the original type).
It appears to be a conscious choice on Clang's part given the possible
benefits. Am i correct in assuming that?
if yes, then is this target-dependent?
and is there a pass to disable this?

-- 
Farzad Sadeghi
project mutator-https://github.com/bloodstalker/mutator



More information about the cfe-dev mailing list