On Thu, 22 Apr 2021 at 15:59, Martin Sebor <mse...@gmail.com> wrote: > > On 4/22/21 2:52 AM, Jonathan Wakely wrote: > > On Thu, 22 Apr 2021, 08:47 Martin Liška, wrote: > > > > On 4/21/21 6:11 PM, Martin Sebor wrote: > > > On 4/21/21 2:15 AM, Martin Liška wrote: > > >> Hello. > > >> > > >> It's addressing the following Clang warning: > > >> cp/lex.c:170:45: warning: result of comparison of constant 64 > > with expression of type 'enum ovl_op_code' is always true > > [-Wtautological-constant-out-of-range-compare] > > >> > > >> Patch can bootstrap on x86_64-linux-gnu and survives regression > > tests. > > >> > > >> Ready to be installed? > > >> Thanks, > > >> Martin > > >> > > >> gcc/cp/ChangeLog: > > >> > > >> * cp-tree.h (STATIC_ASSERT): Prefer static assert. > > >> * lex.c (init_operators): Remove run-time check. > > >> --- > > >> gcc/cp/cp-tree.h | 3 +++ > > >> gcc/cp/lex.c | 2 -- > > >> 2 files changed, 3 insertions(+), 2 deletions(-) > > >> > > >> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > > >> index 81ff375f8a5..a8f72448ea9 100644 > > >> --- a/gcc/cp/cp-tree.h > > >> +++ b/gcc/cp/cp-tree.h > > >> @@ -5916,6 +5916,9 @@ enum ovl_op_code { > > >> OVL_OP_MAX > > >> }; > > >> +/* Make sure it fits in lang_decl_fn::operator_code. */ > > >> +STATIC_ASSERT (OVL_OP_MAX < (1 << 6)); > > >> + > > > > > > I wonder if there's a way to test this directly by something like > > > > > > static_assert (number-of-bits (ovl_op_info_t::ovl_op_code) > > > <= number-of-bits (lang_decl_fn::operator_code)); > > > > Good point, but I'm not aware of it. Maybe C++ people can chime in? > > > > > > ovl_op_code is an unscoped enumeration (meaning "enum" not "enum class") > > with no fixed underlying type (i.e. no enum-base like ": int" or ": > > long" is specified) which means that the number of bits in is value > > representation is the number of bits needed to represent the minimum and > > maximum enumerators: > > > > "the values of the enumeration are the values representable by a > > hypothetical integer type with minimal width M such that all enumerators > > can be represented." > > > > There is no function/utility like number-of-bits that can tell you that > > from the type though.You could use > > std::underlying_type<ovl_op_code>::type to get the integral type that > > the compiler used to represent it, but that will probably be 'int' in > > this case and so all it tells you is an upper bound of no more than 32 > > bits, which is not useful for this purpose. > > I suspected there wasn't a function like that. Thanks for confirming > it. I wrote the one below just to see if it could be done. It works > for one bit-field but I can't think of a way to generalize it. We'd > probably need a built-in for that. Perhaps one might be useful. > > enum E { e = 5 }; > struct A { E e: 3; }; > > constexpr int number_of_bits () > { > A a = { }; > a.e = (E)-1; > int n = 0; > for (; a.e; ++n) > a.e = (E)((unsigned)a.e ^ (1 << n)); > return n; > } > > Martin
Or: enum E { e = 5 }; struct A { E e: 3; }; constexpr int number_of_bits () { A a = { }; a.e = (E)-1; return 32 - __builtin_clz(a.e); } But you can't get the number-of-bits needed for all the values of the enum E, which is what I was referring to. If you know the enumerators go from 0 to MAX (as is the case for ovl_op_code) you can use (32 - __builtin_clz(MAX)) there too, but in the general case you don't always know the maximum enumerator without checking, and it depends whether the enumeration has a fixed underlying type.