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

Martin Sebor msebor@gmail.com
Thu Nov 12 18:09:00 GMT 2015


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__: ;
     ;
     }
}

Martin



More information about the Gcc-patches mailing list