<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/89367>89367</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [BUG] Clang-tidy: False positive when using `hicpp-signed-bitwise.IgnorePositiveIntegerLiterals`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-tidy
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          sdimovv
      </td>
    </tr>
</table>

<pre>
    Consider the following code:

```c
#include "stdint.h"
#include "stdio.h"
#include "inttypes.h"

int main(void) {
 uint32_t u32val = 0;

    printf("%"PRIu32, u32val & 1);
 printf("%"PRIu32, u32val << 2);

    return 0;
}
```

And the following config:

```yaml
# .clang-tidy
---
FormatStyle: file
WarningsAsErrors: '*'
Checks: >
  -*,
 hicpp-signed-bitwise,
CheckOptions:
 hicpp-signed-bitwise.IgnorePositiveIntegerLiterals: true
```

When `clang-tidy` is ran this is the result:

```
test.c:8:32: error: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise,-warnings-as-errors]
    8 |     printf("%"PRIu32, u32val & 1);
      |                              ~ ^
```

The docs for the `IgnorePositiveIntegerLiterals` option state:

> If this option is set to true, the check will not warn on bitwise operations with positive integer literals.

What I believe is happening here is that implicit conversions are not skipped for the RHS operand, thus when performing the `&` op, the literal `1` is implicitly cast from an `int` to an `unsigned int`, and is no longer considered a literal. 

But the same thing doesn't happen for the `<<` operation, because for that operation the operands on both sides do not have to be the same type, thus the literal `2` is not implicitly casted.

Note that implicit casts are skipped for the LHS operand. This can be observed with the following code:

```c
#include "stdint.h"
#include "stdio.h"
#include "inttypes.h"

int main(void) {
    uint8_t u8val = 0;

    printf("%"PRIu8, u8val & 1);
 printf("%"PRIu8, u8val << 2);

    return 0;
}
```

The above code raises no errors when checked with `clang-tidy`, even though `u8val` is implicitly casted to an `int` for both the `&` and `<<` operations.


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUVk2P2zYQ_TX0ZSBDpmxZPvjgj3W7QNAGSYocC0oaS2xoUiBHNnzpby9Iyh_rxEET9FJhoZU8HHLmvTczEs7JRiMu2WzNZtuR6Kk1dulqeTDH46g09Xm5MdrJGi1Qi7A3SpmT1A1UpkaWrVi6ZenlnqfxrxreeSZ1pfoagXHuqJaaxi3j_JnZPLVKTXTu0N0vCHepCQ5CasaLo5E14wtg83W0QS81ZfxPgj7jR6GAZVtIWba-3wAAoLNS057xwm_OZ4zz9x9e-4wzvrm68hwmjC-u3v_KKduwbAP83u92qkXqrb4PaL59APLeZaXrryjQe9k8I-EsDuoKJYwrJXSTkKzP8cckSeLDztiDoI90Vp5P2EuF0fBZWC1141buxVpjnbcyPmd85e9hyabF6ks0ZC-XzJKwYjO8trLquiTIrE5KSSfp8GoN_r93JI121zy-6TJ-bbSx-N44SfKIr5qwQftOElqhQgRke_wOfJ9b1OC1ecMhT0E6sEIDtdL5Z4-vRdcreoZqfCV0NK5YtipYtsq4Px49Rv6hdwhmDwJiAiBjqGA6tELXcJLUgoBSamHPMKQXrWQssNn6CWTJaSAkES7BSMlse9NTAWy-gZ_Wc7guOzy9_gY2e_kOzJ9ahNpUDvYmdgyWp9-nLk_BBAWAI0Ff9ZTsBV73kaBhmXTgkIBMpJxvwjmVlxKcpFKgDYHHCox-wNfrLBLQDdFc6VFDPOO3ohEEr1CikujXOmhF16FnAVq0GDUjCOShU7KS5GvyiNaFg4TFEIv7IrsO6yskH379eFFDjL53cPLy7NDujT343QfoGM8jQJc0hzC9bTII-HK2OkMlHMHemgOIIHapyS8iM7z3-ibKsPsGvCSlA21AGe2BqIZ-jzWIy3FjuEdl3VOIxYkDemZ0A7VBpxmf0wDQPf2xC8Y0BhL8wSVWwtdKXCnoZg2OA0AukGioBR-Ug9oESFtxRJ9WiXeRnDu84vmAFR-w8r4PeGH9hvLfDOEjp8JRZPORyXc3JsfwyWu0EtoHZUqH9ohDtf__JidAGJ6Fn53Fj4_OInSa4kcG573Lfzk2fUMSpTliwB2skA6D3GMHjYUXmseFrcch4QPDI3pZmr4J9hDnt8sP61u5DeXn1RIk_LaofeV9uzzeNqFRvczqRbYQI1xO5pNsxrM8TUftMhU4r8tpNp2lRVruJ_NyP0_zSS3SqqiqohrJJU_5NJ1OFpN0mk_TcZqLaTnLuRCzsuDZgk1TPAipxkodD2Njm5F0rsdlscjy-UiJEpUL34ac30HCuf9WtEvvlJR949g0VdKRu21DklT4qlz_8QubbWFz885WsBPK4a0FBwp652uD5elPTP88HfVWLVuiLnxG8B3ju0ZS25fjyhwY3_nAhn9JZ81fWBHju5CsY3wX8v0nAAD__8J5V18">