This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC, C] add warning for unpromoted bit-field uses


> We had a request from a customer to add a warning to the C front end to
> diagnose cases where bit-fields larger than an int are used in shift
> expressions; confusingly, the operation is done in the precision of the
> bit-field size rather than its declared type. This is a symptom of a larger
> problem, of course, as it affects bit-field uses in other expressions
> besides shifts, too.
>
>
> The C standard specifies that bit-fields have an integral type of the
> specified number of bits. On the other hand, in C++, bit-fields do have
> their declared type, so it seems appropriate to tie the new proposed warning
> to -Wc++-compat.

The message:
> +    warning_at (EXPR_LOCATION (exp), OPT_Wbitfield_conversion,
> +            "suggest casting bit-field to its declared type");

is not very clear without the context of your email. Could it explain
what is (or could) be wrong? For example, "ISO C specifies that this
bit-field is implicitly converted to type %qT rather than its declared
type (%qT)". And a note at lhs location could say "use an explicit
cast to silence this warning".

Nonetheless, perhaps I'm missing something but Wconversion seems to
think that the promotion of sp->a and sp->c is always to 'int':

test.c:17:10: warning: conversion to 'long long unsigned int' from
'int' may change the sign of the result [-Wsign-conversion]
   temp = sp->a << 1;
          ^
test.c:18:10: warning: conversion to 'long long unsigned int' from
'int' may change the sign of the result [-Wsign-conversion]
   temp = sp->a + 1;
          ^
test.c:19:10: warning: conversion to 'long long unsigned int' from
'int' may change the sign of the result [-Wsign-conversion]
   temp = sp->a * 2;
          ^
test.c:28:10: warning: conversion to 'long long unsigned int' from
'int' may change the sign of the result [-Wsign-conversion]
   temp = sp->c << 1;  /* { dg-warning "suggest casting bit-field to
its declared type" } */
          ^
test.c:29:10: warning: conversion to 'long long unsigned int' from
'int' may change the sign of the result [-Wsign-conversion]
   temp = sp->c + 1;  /* { dg-warning "suggest casting bit-field to
its declared type" } */
          ^
test.c:30:10: warning: conversion to 'long long unsigned int' from
'int' may change the sign of the result [-Wsign-conversion]
   temp = sp->c * 2;  /* { dg-warning "suggest casting bit-field to
its declared type" } */
          ^

And clang (mostly) agrees:

test.c:17:16: warning: implicit conversion changes signedness: 'int'
to 'unsigned long long' [-Wsign-conversion]
  temp = sp->a << 1;
       ~ ~~~~~~^~~~
test.c:28:16: warning: implicit conversion changes signedness: 'int'
to 'unsigned long long' [-Wsign-conversion]
  temp = sp->c << 1;  /* { dg-warning "suggest casting bit-field to
its declared type" } */
       ~ ~~~~~~^~~~

Cheers,

Manuel.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]