aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2011-09-02 10:28:36 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-09-02 10:28:36 +0000
commit5da7fa30dae5648484fcd8e73add4bbeec0097ee (patch)
tree2385a4a4b5ced97f93fce5652c1b6ebb73402ac0
parentbd38b43159413df75de165990b82bc32ae677e07 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--libstdc++-v3/include/std/bitset25
-rw-r--r--libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc84
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;
+}