[clang] [Clang] Force expressions with UO_Not to not be non-negative (PR #126846)

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 3 12:21:19 PDT 2025


ahatanak wrote:

> > Could you help me understand why clang is emitting the warning?
> > Isn't it semantically equivalent to the following code?
> > ```
> > unsigned int foo(unsigned char x)
> > {
> >      int i = ~(1<<x); // no -Wimplicit-int-conversion warning.
> >      return i; // no -Wimplicit-int-conversion warning.
> > }
> > ```
> 
> The conversion isn't implicit in the latter case.

It looks like the warning is emitted because of the following code in `TryGetExprRange`:

```
    case BO_Shl:
      // ...except that we want to treat '1 << (blah)' as logically
      // positive.  It's an important idiom.
      if (IntegerLiteral *I
            = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
        if (I->getValue() == 1) {
          IntRange R = IntRange::forValueOfType(C, GetExprType(E));
          return IntRange(R.Width, /*NonNegative*/ true);
        }
      }
```

`1<<x` is treated as non-negative even though it can be negative when `x` is equal to 31.

https://github.com/llvm/llvm-project/pull/126846


More information about the cfe-commits mailing list