From mboxrd@z Thu Jan 1 00:00:00 1970 From: anders@ieee.org To: libstdc++-gnats@sourceware.cygnus.com Subject: libstdc++/1857: bitset::operator<<= and >>= incorrect for multiples of 32 Date: Sun, 01 Apr 2001 00:00:00 -0000 Message-id: <20000310045438.17716.qmail@sourceware.cygnus.com> X-SW-Source: 2001-q1/msg00883.html List-Id: >Number: 1857 >Category: libstdc++ >Synopsis: bitset::operator<<= and >>= incorrect for multiples of 32 >Confidential: no >Severity: serious >Priority: medium >Responsible: bkoz >State: analyzed >Class: sw-bug >Submitter-Id: net >Arrival-Date: Sat Feb 03 09:26:07 PST 2001 >Closed-Date: >Last-Modified: Wed Mar 22 11:17:00 PST 2000 >Originator: Anders Johnson >Release: libstdc++-2.90.7 >Organization: >Environment: SunOS thresher 5.6 Generic_105181-05 sun4u sparc SUMW,Ultra-60 >Description: The implementation of bitset relies on the behavior of _WordT >> __BITS_PER_WORDT(_WordT), which is not defined according to the C standard, and is equivalent to _WordT >> 0 on the Sparc. This occurs whenever the shift amount is a multiple of __BITS_PER_WORDT(_WordT). >How-To-Repeat: >Fix: The expressions on lines 201 and 220 of stl/bits/std_bitset.h should read (__offset ? ... : static_cast<_WordT>(0)) instead. >Release-Note: >Audit-Trail: Formerly PR libstdc++/40 From: Benjamin Kosnik To: anders@ieee.org Cc: libstdc++-gnats@sourceware.cygnus.com, libstdc++-prs@sourceware.cygnus.com Subject: Re: libstdc++/40: bitset::operator<<= and >>= incorrect for multiples of 32 Date: Fri, 10 Mar 2000 11:17:48 -0800 (PST) can you please send me a patch and change log entry? thanks, benjamin On 10 Mar 2000 anders@ieee.org wrote: > > >Number: 40 > >Category: libstdc++ > >Synopsis: bitset::operator<<= and >>= incorrect for multiples of 32 > >Confidential: no > >Severity: serious > >Priority: medium > >Responsible: unassigned > >State: open > >Class: sw-bug > >Submitter-Id: net > >Arrival-Date: Thu Mar 09 20:57:00 PST 2000 > >Closed-Date: > >Last-Modified: > >Originator: Anders Johnson > >Release: libstdc++-2.90.7 > >Organization: > >Environment: > SunOS thresher 5.6 Generic_105181-05 sun4u sparc SUMW,Ultra-60 > >Description: > The implementation of bitset relies on the behavior > of _WordT >> __BITS_PER_WORDT(_WordT), which is not > defined according to the C standard, and is equivalent > to _WordT >> 0 on the Sparc. This occurs whenever the > shift amount is a multiple of __BITS_PER_WORDT(_WordT). > >How-To-Repeat: > > >Fix: > The expressions on lines 201 and 220 of stl/bits/std_bitset.h > should read (__offset ? ... : static_cast<_WordT>(0)) instead. > >Release-Note: > >Audit-Trail: > >Unformatted: > Responsible-Changed-From-To: unassigned->bkoz Responsible-Changed-By: bkoz Responsible-Changed-When: Wed Mar 22 00:30:10 2000 Responsible-Changed-Why: mine State-Changed-From-To: open->analyzed State-Changed-By: bkoz State-Changed-When: Wed Mar 22 00:30:10 2000 State-Changed-Why: Can you please send in a patch for this? From: bkoz@cygnus.com To: anders@ieee.org, bkoz@cygnus.com, libstdc++-gnats@sourceware.cygnus.com, nobody@sourceware.cygnus.com Cc: Subject: Re: libstdc++/40 Date: 22 Mar 2000 08:30:10 -0000 Synopsis: bitset::operator<<= and >>= incorrect for multiples of 32 Responsible-Changed-From-To: unassigned->bkoz Responsible-Changed-By: bkoz Responsible-Changed-When: Wed Mar 22 00:30:10 2000 Responsible-Changed-Why: mine State-Changed-From-To: open->analyzed State-Changed-By: bkoz State-Changed-When: Wed Mar 22 00:30:10 2000 State-Changed-Why: Can you please send in a patch for this? http://sourceware.cygnus.com/cgi-bin/gnatsweb.pl?cmd=view&pr=40&database=libstdc++ From: Benjamin Kosnik To: Anders Johnson Cc: libstdc++-gnats@sourceware.cygnus.com Subject: Re: libstdc++/40 Date: Wed, 22 Mar 2000 11:05:11 -0800 (PST) No, I did not get your patch. Can you please resend, and cc libstdc++-gnats? That way it gets logged in the database. thanks, benjamin From: anders@broadcom.com (Anders Johnson) To: bkoz@cygnus.com Cc: libstdc++-gnats@sourceware.cygnus.com Subject: Re: libstdc++/40 Date: Wed, 22 Mar 2000 11:13:14 -0800 ----- Begin Included Message ----- From anders Fri Mar 10 16:23:54 2000 To: bkoz@cygnus.com Subject: Re: libstdc++/40: bitset::operator<<= and >>= incorrect for multiples of 32 > can you please send me a patch and change log entry? I'm new at this, so please bear with me. The problem was actually observed on gcc/2.95.2/5.6/include/g++-3, because I can't build libstdc++-2.90.7 on my system because "wmemcmp.c" doesn't compile because 'wint_t' is not defined in either "string.h" or "stddef.h". However, the code in libstdc++-2.90.7 looks the same. Here is the patch: ----- Begin Included File ----- diff -c3pr libstdc++-2.90.7-1/stl/bits/std_bitset.h libstdc++-2.90.7/stl/bits/std_bitset.h *** libstdc++-2.90.7/stl/bits/std_bitset.h Tue Dec 21 21:07:58 1999 --- NEW/stl/bits/std_bitset.h Fri Mar 10 14:50:36 2000 *************** void _Base_bitset<_Nw, _WordT>::_M_do_le *** 196,204 **** const size_t __offset = __shift % __BITS_PER_WORDT(_WordT); const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; size_t __n = _Nw - 1; ! for ( ; __n > __wshift; --__n) ! _M_w[__n] = (_M_w[__n - __wshift] << __offset) | ! (_M_w[__n - __wshift - 1] >> __sub_offset); if (__n == __wshift) _M_w[__n] = _M_w[0] << __offset; for (size_t __n1 = 0; __n1 < __n; ++__n1) --- 196,206 ---- const size_t __offset = __shift % __BITS_PER_WORDT(_WordT); const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; size_t __n = _Nw - 1; ! for ( ; __n > __wshift; --__n) { ! _M_w[__n] = (_M_w[__n - __wshift] << __offset); ! if(__offset) ! _M_w[__n] |= _M_w[__n - __wshift - 1] >> __sub_offset; ! } if (__n == __wshift) _M_w[__n] = _M_w[0] << __offset; for (size_t __n1 = 0; __n1 < __n; ++__n1) *************** void _Base_bitset<_Nw, _WordT>::_M_do_ri *** 215,223 **** const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; const size_t __limit = _Nw - __wshift - 1; size_t __n = 0; ! for ( ; __n < __limit; ++__n) ! _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | ! (_M_w[__n + __wshift + 1] << __sub_offset); _M_w[__limit] = _M_w[_Nw-1] >> __offset; for (size_t __n1 = __limit + 1; __n1 < _Nw; ++__n1) _M_w[__n1] = static_cast<_WordT>(0); --- 217,227 ---- const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; const size_t __limit = _Nw - __wshift - 1; size_t __n = 0; ! for ( ; __n < __limit; ++__n) { ! _M_w[__n] = (_M_w[__n + __wshift] >> __offset); ! if(__offset) ! _M_w[__n] |= _M_w[__n + __wshift + 1] << __sub_offset; ! } _M_w[__limit] = _M_w[_Nw-1] >> __offset; for (size_t __n1 = __limit + 1; __n1 < _Nw; ++__n1) _M_w[__n1] = static_cast<_WordT>(0); ----- End Included File ----- Here is a ChangeLog entry (not sure about the format): ----- Begin Included File ----- - Fri Mar 10 16:12:00 PST 2000 stl/bits/std_bitset.h: Modified _M_do_left_shift and _M_do_right_shift not to rely on the behavior of _WordT << __BITS_PER_WORDT(_WordT), which is undefined according to the C standard, and does the wrong thing on Sparc. ----- End Included File ----- Here is a test case: ----- Begin Included File ----- #include #include #include #include int main() { bitset<66> b(1); cout << b << endl; b<<=32; cout << b << endl; b |= bitset<66>(1)<<65; cout << b << endl; b>>=32; cout << b << endl; return 0; } ----- End Included File ----- The expected output is: 000000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000100000000000000000000000000000000 100000000000000000000000000000000100000000000000000000000000000000 000000000000000000000000000000001000000000000000000000000000000001 The actual output on SunOS 5.5.1 sun4u sparc is: 000000000000000000000000000000000000000000000000000000000000000001 010000000000000000000000000000000100000000000000000000000000000000 110000000000000000000000000000000100000000000000000000000000000000 000000000000000000000000000000001100000000000000000000000000000011 Please let me know if you need anything else. Thanks, -- n _ _ _ Anders Johnson ``The ultimate test of all X /_)|' (_` Broadcom Corporation knowledge is experiment.'' (_X\_,| ._) anders(at)ieee(dot)org -- Richard Feynman ----- End Included Message ----- >Unformatted: