diff options
| author | Marshall Clow <mclow.lists@gmail.com> | 2017-11-27 19:03:30 +0000 | 
|---|---|---|
| committer | Marshall Clow <mclow.lists@gmail.com> | 2017-11-27 19:03:30 +0000 | 
| commit | 14d7aac15dafa4e2622dd9ba284044977d40363f (patch) | |
| tree | 666ef0de21e3ff259f5ba4bca082adb9b66b0e9c | |
| parent | cbdd238d5e70e88e6d7d552cdc35d17795a3a55d (diff) | |
| download | bcm5719-llvm-14d7aac15dafa4e2622dd9ba284044977d40363f.tar.gz bcm5719-llvm-14d7aac15dafa4e2622dd9ba284044977d40363f.zip  | |
Fix PR#35438 - bitset constructor does not zero unused bits
llvm-svn: 319074
3 files changed, 24 insertions, 2 deletions
diff --git a/libcxx/include/bitset b/libcxx/include/bitset index 583122fbfda..e26e674dd33 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -503,7 +503,10 @@ template <size_t _Size>  inline  _LIBCPP_CONSTEXPR  __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT -    : __first_(static_cast<__storage_type>(__v)) +    : __first_( +        _Size == __bits_per_word ? static_cast<__storage_type>(__v) +                                 : static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1) +    )  {  } diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp index a2c9df6b4a2..fb3502983e6 100644 --- a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp +++ b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp @@ -36,11 +36,18 @@ void test_to_ullong()          std::bitset<N> v(j);          assert(j == v.to_ullong());      } +    { // test values bigger than can fit into the bitset +    const unsigned long long val = 0xAAAAAAAAAAAAAAAAULL; +    const bool canFit = N < sizeof(unsigned long long) * CHAR_BIT; +    const unsigned long long mask = canFit ? (1ULL << N) - 1 : (unsigned long long)(-1); +    std::bitset<N> v(val); +    assert(v.to_ullong() == (val & mask)); // we shouldn't return bit patterns from outside the limits of the bitset. +    }  }  int main()  { -    test_to_ullong<0>(); +//     test_to_ullong<0>();      test_to_ullong<1>();      test_to_ullong<31>();      test_to_ullong<32>(); diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp index 7cabd06e5f3..86b481579f3 100644 --- a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp +++ b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp @@ -16,9 +16,12 @@  #include <climits>  #include <cassert> +#include <iostream> +  template <std::size_t N>  void test_to_ulong()  { +    std::cout << "Testing size = " << N << std::endl;      const std::size_t M = sizeof(unsigned long) * CHAR_BIT < N ? sizeof(unsigned long) * CHAR_BIT : N;      const bool is_M_zero = std::integral_constant<bool, M == 0>::value; // avoid compiler warnings      const std::size_t X = is_M_zero ? sizeof(unsigned long) * CHAR_BIT - 1 : sizeof(unsigned long) * CHAR_BIT - M; @@ -34,9 +37,18 @@ void test_to_ulong()      for (std::size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i)      {          std::size_t j = tests[i]; +    std::cout << "  Testing value = " << j << std::endl;          std::bitset<N> v(j);          assert(j == v.to_ulong());      } + +    { // test values bigger than can fit into the bitset +    const unsigned long val = 0xAAAAAAAAULL; +    const bool canFit = N < sizeof(unsigned long) * CHAR_BIT; +    const unsigned long mask = canFit ? (1ULL << N) - 1 : (unsigned long)(-1); +    std::bitset<N> v(val); +    assert(v.to_ulong() == (val & mask)); // we shouldn't return bit patterns from outside the limits of the bitset. +    }  }  int main()  | 

