Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

-Wconversion misses non-elided integral promotion. #36143

Open Quuxplusone opened 6 years ago

Quuxplusone commented 6 years ago
Bugzilla Link PR37170
Status NEW
Importance P normal
Reported by Nicholas Baldwin (nicholasjbbaldwin@gmail.com)
Reported on 2018-04-18 14:43:33 -0700
Last modified on 2018-04-18 14:49:00 -0700
Version trunk
Hardware PC Linux
CC llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments wconversion_bug.png (364801 bytes, image/png)
Blocks
Blocked by
See also
Integral promotion of smaller int types (e.g. uint8_t) can be elided when no
difference in observable behavior happens. Thus when -Wconversion is turned on
and the promotion is elided, no warning is reported as it should.

However, in the case where elision cannot happen (such as the following code
sample) and integral promotion clearly takes place, -Wconversion still reports
no error.

#include <stdint.h>
uint8_t test(void);

uint8_t test() {
    uint8_t a = 0x5a;
    uint8_t c = (uint8_t)(~(int)a) >> 4;
    return c;
}

will return 0x05 and produces no errors (correct).

#include <stdint.h>
uint8_t test(void);

uint8_t test() {
    uint8_t a = 0x5a;
    uint8_t c = (~a) >> 4;
    return c;
}

will return 0xf5 and still produces no errors (incorrect). Since a is clearly
being promoted to an int, -Wconversion should warn that a the integer
conversion is losing precision.

I've attached a screenshot of the difference in code gen.
Quuxplusone commented 6 years ago

Attached wconversion_bug.png (364801 bytes, image/png): Screenshot of godbolt excercising the issue.

Quuxplusone commented 6 years ago
(In reply to Nicholas Baldwin from comment #0)
> Integral promotion of smaller int types (e.g. uint8_t) can be elided when no
> difference in observable behavior happens. Thus when -Wconversion is turned
> on and the promotion is elided, no warning is reported as it should.
>
> However, in the case where elision cannot happen (such as the following code
> sample) and integral promotion clearly takes place, -Wconversion still
> reports no warnings.
>
> #include <stdint.h>
> uint8_t test(void);
>
> uint8_t test() {
>     uint8_t a = 0x5a;
>     uint8_t c = (uint8_t)(~(int)a) >> 4;
>     return c;
> }
>
> will return 0x05 and produces no warnings (correct).
>
> #include <stdint.h>
> uint8_t test(void);
>
> uint8_t test() {
>     uint8_t a = 0x5a;
>     uint8_t c = (~a) >> 4;
>     return c;
> }
>
> will return 0xf5 and still produces no warnings(incorrect). Since a is
> clearly being promoted to an int, -Wconversion should warn that a the
> integer conversion is losing precision.
>
> I've attached a screenshot of the difference in code gen.

Used incorrect noun, meant to say that it produces no warnings, not no errors.