https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93589

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |NEW
   Last reconfirmed|                            |2020-02-15
         Resolution|INVALID                     |---
     Ever confirmed|0                           |1

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #4)
> The warning was just

Oops, I meant to say the warning was just suppressed for the += case, see PR
40752.

(In reply to John Downing from comment #5)
> This will generate a warning, for the char and short cases, when the "|="
> happens.  This is despite "val" being explicitly declared as a char or an
> short.

It's not *despite* being declared as char or short, it's *because* they are
declare as char and short.

> I can see this being correct if "val" has been declared as "unsigned", which
> i shorthand for "unsigned int".  But if "val" is explicitly declared as
> something, there should be a potential for the conversion to change the
> value.

That's not true. Given:

  val |= (CHAR_BIT * static_cast<char>(i)) << (CHAR_BIT *
static_cast<char>(i));

The type of (CHAR_BIT * static_cast<char>(i)) is int, due to:
https://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion

And the type of the entire right-hand side is int, so you are doing val |=
int(some_value) which the compiler correctly says might not fit in a short or
char. In this specific case, your loop conditions mean that the value of the
right hand side will fit, but the warning doesn't know about the values, it
only cares that conversion from int to short int involves a potentially lossy
conversion.

The fact that GCC still warns for this case seems like a bug though:

      val |= static_cast<char>((CHAR_BIT * i) << (CHAR_BIT * i));

Even though the right operand still gets promoted to type 'int', it clearly
doesn't have a value that would be changed by the conversion.

Reply via email to