[patch] libstdc++/56158 Extend valid values of iostream bitmask types

Jonathan Wakely jwakely@redhat.com
Fri Nov 13 08:39:00 GMT 2015


On 12/11/15 11:09 -0700, Martin Sebor wrote:
>On 11/12/2015 10:08 AM, Jonathan Wakely wrote:
>>On 12/11/15 08:48 -0700, Martin Sebor wrote:
>>>On 11/11/2015 02:48 AM, Jonathan Wakely wrote:
>>>>As described in the PR, we have operator~ overloads defined for
>>>>enumeration types which produce values outside the range of valid
>>>>values for the type. In C++11 that can be trivially solved by giving
>>>>the enumeration types a fixed underlying type, but this code needs to
>>>>be valid in C++03 too.
>>>>
>>>>This patch defines new min/max enumerators as INT_MIN/INT_MAX so that
>>>>every int value is also a valid value for the bitmask type.
>>>>
>>>>Does anyone see any problems with this solution, or better solutions?
>>>
>>>Just a minor nit that the C-style cast in the below triggers
>>>a -Wold-style-cast warning in Clang, in case libstdc++ tries
>>>to be Clang-warning free. Since the type of __INT_MAX__ is
>>>int it shouldn't be necessary.
>>>
>>>+      _S_ios_fmtflags_min = ~(int)__INT_MAX__
>>
>>That's worth fixing, thanks.
>>
>>>>
>>>>Any suggestions for how to test this, given that GCC's ubsan doesn't
>>>>check for this, and we can't run the testsuite with ubsan anyway?
>>>
>>>Use a case/switch statement with -Werror=switch-enum to make sure
>>>all the cases are handled and none is duplicated or outside of the
>>>valid values of the enumeration:
>>>
>>> void foo (ios::iostate s) {
>>>     switch (s) {
>>>     case badbit:
>>>     case eofbit:
>>>     case failbit:
>>>     case goodbit:
>>>     case __INT_MAX__:
>>>     case ~__INT_MAX__: ;
>>>   }
>>> }
>>
>>I thought this was a great idea at first ... but -Wswitch-enum will
>>complain that the end, min and max enumerators are not handled (even
>>though __INT_MAX__ and ~__INT_MAX__ have the same values as the max
>>and min ones, respectively).
>
>Hmm, I didn't see any warnings for the small test case I wrote and
>still don't. Just out of curiosity, what did I miss?
>
>enum iostate {
>    goodbit = 0,
>    eofbit,
>    failbit,
>    badbit,
>    max = __INT_MAX__,
>    min = ~__INT_MAX__
>};
>
>void foo (iostate s) {
>    switch (s) {
>    case badbit:
>    case eofbit:
>    case failbit:
>    case goodbit:
>    case __INT_MAX__:
>    case ~__INT_MAX__: ;
>    ;
>    }
>}

I must have messed up my test, I agree this is warning clean.

So I could add tests for those minimum and maximum values, and also
static_assert that the enumerations have an underlying type with the
same representation as int (because if it's actually bigger than int
the operator~ could still produce values outside the range of valid
values).



More information about the Gcc-patches mailing list