Hi, consider the following code:
uint16_t testa4(uint8_t x, uint8_t y) { return ( (uint16_t)x << 0 ) | ( (uint16_t)y << 8 ); } uint16_t testb3(uint16_t x, uint16_t y) { return x|y; } uint16_t testb4(uint16_t x, uint16_t y) { return x+y; } int testb4x(uint16_t x, uint16_t y) { return x+y; } I'm using clang 11.0.0 on Intel x86_64 and when I compile the above code with -Wconversion enabled, then I see only one warning, namely for testa4. However, according to the C standard, the expression after the return statement has type int in all 4 cases. So why is the warning not triggered for testb3 and testb4? In fact, it's convenient that testb3 does not trigger a warning. Yes, x and y are promoted to int before the bitwise or is performed, but the result indeed fits into an uint16_t, regardless of x and y. So if clang is smart and keeps track of the range of the expressions, then it is understandable that there is no warning for testb3. However, then the "keeping track of ranges" feature seems to fail for testa4, because there a warning is indeed produced even though the two operands of the bitwise-or are both uint16_t. However, the case of testb4 is different. If we set x an y to 0xFFFF, then the result will be 0x1FFFE. You can confirm that this is the case by running testb4x. Then, shouldn't testb4 trigger a warning? The result is clearly and int _and_ the result may not fit into an uint16_t. I'm lost. As far as I understand, -Wconversion should issue a warning when an int is converted to uint16_t without an explicit cast. For all I know, x+y and x|y are ints, yet there is no warning in testb3 and testb4. This seems like a bug to me. Can you elaborate what is happening here? Kind Regards, Sven _______________________________________________ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users