This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC, C] add warning for unpromoted bit-field uses
- From: Manuel López-Ibáñez <lopezibanez at gmail dot com>
- To: Sandra Loosemore <sandra at codesourcery dot com>, Gcc Patch List <gcc-patches at gcc dot gnu dot org>, "Joseph S. Myers" <joseph at codesourcery dot com>
- Date: Sun, 9 Nov 2014 10:28:13 +0100
- Subject: Re: [RFC, C] add warning for unpromoted bit-field uses
- Authentication-results: sourceware.org; auth=none
> 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.