Issue |
133497
|
Summary |
UBSan should not warn on integer overflow with downcast or bitwise-AND mask
|
Labels |
new issue
|
Assignees |
|
Reporter |
Explorer09
|
### Test code
```c
#include <stdint.h>
#include <stdio.h>
static inline unsigned int popCount8(uint8_t x) {
// Formula borrowed from https://github.com/llvm/llvm-project/issues/79823
uint32_t n = (uint32_t)(x * 0x08040201U);
n = ((((n >> 3) & 0x11111111U) * 0x11111111U) & 0xF0000000U) >> 28;
return n;
}
int main(void) {
volatile uint8_t x;
x = 0xFF;
// Expected output: 8
printf("%u\n", popCount8(x));
return 0;
}
```
Compile with: `clang -fsanitize=integer -o test test.c`
Then run with `./test`
### Actual behavior
```
test1.c:6:30: runtime error: unsigned integer overflow: 255 * 134480385 cannot be represented in type 'unsigned int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test1.c:6:30 in
test1.c:7:35: runtime error: unsigned integer overflow: 286331153 * 286331153 cannot be represented in type 'unsigned int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test1.c:7:44 in
```
### Expected behavior
No errors and no warnings.
The compiler and UndefinedBehaviorSanitizer should not warn about both overflow cases as I have made downcasts and bitwise-AND masks to tell that the "overflows" are intentional.
* `(uint32_t)(x * 0x08040201U)`
* `((x * 0x11111111U) & 0xF0000000U)`
While I can workaround the bug by adding a upcast like this...
* `(uint32_t)((uint64_t)x * 0x08040201U)`
* `(((uint64_t)x * 0x11111111U) & 0xF0000000U)`
... I would rather like conciseness and not needing such casts.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs