From: Paolo Carlini Date: Fri, 2 Sep 2011 10:28:36 +0000 (+0000) Subject: re PR libstdc++/50268 ([C++0x] bitset doesn't sanitize input) X-Git-Tag: releases/gcc-4.7.0~4002 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5da7fa30dae5648484fcd8e73add4bbeec0097ee;p=thirdparty%2Fgcc.git re PR libstdc++/50268 ([C++0x] bitset doesn't sanitize input) 2011-09-02 Paolo Carlini Marc Glisse PR libstdc++/50268 * include/std/bitset (struct _Sanitize_val): Add. (bitset<>::bitset(unsigned long long)): Fix. * testsuite/23_containers/bitset/cons/50268.cc: New. Co-Authored-By: Marc Glisse From-SVN: r178463 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 386a15e3de71..bd9850cd43b9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2011-09-02 Paolo Carlini + Marc Glisse + + PR libstdc++/50268 + * include/std/bitset (struct _Sanitize_val): Add. + (bitset<>::bitset(unsigned long long)): Fix. + * testsuite/23_containers/bitset/cons/50268.cc: New. + 2011-09-01 Paolo Carlini * include/bits/hashtable.h (_Hashtable<>::_Hashtable(_Hashtable&&)): diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset index 5829726c5b02..648d7ab5fe8e 100644 --- a/libstdc++-v3/include/std/bitset +++ b/libstdc++-v3/include/std/bitset @@ -52,11 +52,13 @@ #include #include -#define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * sizeof(unsigned long)) +#define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_LONG__) #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \ ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1)) +#define _GLIBCXX_BITSET_BITS_PER_ULL (__CHAR_BIT__ * __SIZEOF_LONG_LONG__) + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_CONTAINER @@ -657,6 +659,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _S_do_sanitize(_WordT) _GLIBCXX_NOEXCEPT { } }; +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + struct _Sanitize_val + { + static constexpr unsigned long long + _S_do_sanitize_val(unsigned long long __val) + { return __val; } + }; + + template + struct _Sanitize_val<_Nb, true> + { + static constexpr unsigned long long + _S_do_sanitize_val(unsigned long long __val) + { return __val & ~((~static_cast(0)) << _Nb); } + }; +#endif + /** * @brief The %bitset class represents a @e fixed-size sequence of bits. * @@ -822,7 +842,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Initial bits bitwise-copied from a single word (others set to zero). #ifdef __GXX_EXPERIMENTAL_CXX0X__ constexpr bitset(unsigned long long __val) noexcept - : _Base(__val) { } + : _Base(_Sanitize_val<_Nb>::_S_do_sanitize_val(__val)) { } #else bitset(unsigned long __val) : _Base(__val) @@ -1513,6 +1533,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER #undef _GLIBCXX_BITSET_WORDS #undef _GLIBCXX_BITSET_BITS_PER_WORD +#undef _GLIBCXX_BITSET_BITS_PER_ULL #ifdef __GXX_EXPERIMENTAL_CXX0X__ diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc b/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc new file mode 100644 index 000000000000..6a61d7e2f13c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc @@ -0,0 +1,84 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +// libstdc++/50268 +void test01() +{ + bool test __attribute__((unused)) = true; + + std::bitset<1> b1(3ULL); + VERIFY( b1.count() == 1ULL ); + + std::bitset<3> b2(30ULL); + VERIFY( b2.count() == 2ULL ); + + std::bitset<6> b3(300ULL); + VERIFY( b3.count() == 3ULL ); + + std::bitset<9> b4(3000ULL); + VERIFY( b4.count() == 5ULL ); + + std::bitset<16> b5(300000ULL); + VERIFY( b5.count() == 7ULL ); + + std::bitset<24> b6(30000000ULL); + VERIFY( b6.count() == 9ULL ); + + std::bitset<32> b7(30000000000ULL); + VERIFY( b7.count() == 13ULL ); + + std::bitset<37> b8(3000000000000ULL); + VERIFY( b8.count() == 18ULL ); + + std::bitset<40> b9(30000000000000ULL); + VERIFY( b9.count() == 16ULL ); + + std::bitset<45> b10(30000000000000ULL); + VERIFY( b10.count() == 20ULL ); + + std::bitset<64> b11(30000000000000ULL); + VERIFY( b11.count() == 20ULL ); + + std::bitset<100> b12(30000000000000ULL); + VERIFY( b12.count() == 20ULL ); + + std::bitset<200> b13(30000000000000ULL); + VERIFY( b13.count() == 20ULL ); + + std::bitset<45> b14(18446744073709551615ULL); + VERIFY( b14.count() == 45ULL ); + + std::bitset<64> b15(18446744073709551615ULL); + VERIFY( b15.count() == 64ULL ); + + std::bitset<100> b16(18446744073709551615ULL); + VERIFY( b16.count() == 64ULL ); + + std::bitset<200> b17(18446744073709551615ULL); + VERIFY( b17.count() == 64ULL ); +} + +int main() +{ + test01(); + return 0; +}