diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2011-09-02 10:28:36 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2011-09-02 10:28:36 +0000 |
commit | 5da7fa30dae5648484fcd8e73add4bbeec0097ee (patch) | |
tree | 2385a4a4b5ced97f93fce5652c1b6ebb73402ac0 | |
parent | bd38b43159413df75de165990b82bc32ae677e07 (diff) | |
download | gcc-5da7fa30dae5648484fcd8e73add4bbeec0097ee.zip gcc-5da7fa30dae5648484fcd8e73add4bbeec0097ee.tar.gz gcc-5da7fa30dae5648484fcd8e73add4bbeec0097ee.tar.bz2 |
re PR libstdc++/50268 ([C++0x] bitset doesn't sanitize input)
2011-09-02 Paolo Carlini <paolo.carlini@oracle.com>
Marc Glisse <marc.glisse@normalesup.org>
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 <marc.glisse@normalesup.org>
From-SVN: r178463
-rw-r--r-- | libstdc++-v3/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/std/bitset | 25 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc | 84 |
3 files changed, 115 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 386a15e..bd9850c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2011-09-02 Paolo Carlini <paolo.carlini@oracle.com> + Marc Glisse <marc.glisse@normalesup.org> + + 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 <paolo.carlini@oracle.com> * include/bits/hashtable.h (_Hashtable<>::_Hashtable(_Hashtable&&)): diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset index 5829726..648d7ab 100644 --- a/libstdc++-v3/include/std/bitset +++ b/libstdc++-v3/include/std/bitset @@ -52,11 +52,13 @@ #include <iosfwd> #include <bits/cxxabi_forced.h> -#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<size_t _Nb, bool = _Nb < _GLIBCXX_BITSET_BITS_PER_ULL> + struct _Sanitize_val + { + static constexpr unsigned long long + _S_do_sanitize_val(unsigned long long __val) + { return __val; } + }; + + template<size_t _Nb> + struct _Sanitize_val<_Nb, true> + { + static constexpr unsigned long long + _S_do_sanitize_val(unsigned long long __val) + { return __val & ~((~static_cast<unsigned long long>(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 0000000..6a61d7e --- /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 +// <http://www.gnu.org/licenses/>. + +#include <bitset> +#include <testsuite_hooks.h> + +// 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; +} |