This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/56158] New: bad enum values computed by operator~ in ios_base.h
- From: "richard-gccbugzilla at metafoo dot co.uk" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 30 Jan 2013 23:38:05 +0000
- Subject: [Bug libstdc++/56158] New: bad enum values computed by operator~ in ios_base.h
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56158
Bug #: 56158
Summary: bad enum values computed by operator~ in ios_base.h
Classification: Unclassified
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: richard-gccbugzilla@metafoo.co.uk
The overloaded operator~s defined for the enumerations in ios_base.h have the
following form:
Enum operator~(Enum e) { return Enum(~static_cast<int>(e)); }
The ~ creates values outside the range of values of the enumeration type, so
the cast back to the Enum type has an unspecified value (see
[expr.static.cast]p10), and in practice it produces an Enum value outside the
range of representable values for the Enum type, so behavior is undefined.
Fix:
--- include/bits/ios_base.h
+++ include/bits/ios_base.h
@@ -87,7 +87,7 @@
inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags
operator~(_Ios_Fmtflags __a)
- { return _Ios_Fmtflags(~static_cast<int>(__a)); }
+ { return _Ios_Fmtflags(static_cast<int>(__a) ^
static_cast<int>(_S_ios_fmtflags_end - 1)); }
inline const _Ios_Fmtflags&
operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
@@ -127,7 +127,7 @@
inline _GLIBCXX_CONSTEXPR _Ios_Openmode
operator~(_Ios_Openmode __a)
- { return _Ios_Openmode(~static_cast<int>(__a)); }
+ { return _Ios_Openmode(static_cast<int>(__a) ^
static_cast<int>(_S_ios_openmode_end - 1)); }
inline const _Ios_Openmode&
operator|=(_Ios_Openmode& __a, _Ios_Openmode __b)
@@ -165,7 +165,7 @@
inline _GLIBCXX_CONSTEXPR _Ios_Iostate
operator~(_Ios_Iostate __a)
- { return _Ios_Iostate(~static_cast<int>(__a)); }
+ { return _Ios_Iostate(static_cast<int>(__a) ^
static_cast<int>(_S_ios_iostate_end - 1)); }
inline const _Ios_Iostate&
operator|=(_Ios_Iostate& __a, _Ios_Iostate __b)