mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			PR libstdc++/88113 use size_type consistently instead of size_t
On 16-bit msp430-elf size_t is either 16 bits or 20 bits, and so can't represent all values of the uint32_t type used for bitset::size_type. Using the smaller of size_t and uint32_t for size_type ensures it fits in size_t. PR libstdc++/88113 * src/c++17/memory_resource.cc (bitset::size_type): Use the smaller of uint32_t and size_t. (bitset::size(), bitset::free(), bitset::update_next_word()) (bitset::max_blocks_per_chunk(), bitset::max_word_index()): Use size_type consistently instead of size_t. (chunk): Adjust static_assert checking sizeof(chunk). From-SVN: r266352
This commit is contained in:
		
							parent
							
								
									4cd5da011d
								
							
						
					
					
						commit
						afd02e4c67
					
				|  | @ -1,3 +1,13 @@ | ||||||
|  | 2018-11-21  Jonathan Wakely  <jwakely@redhat.com> | ||||||
|  | 
 | ||||||
|  | 	PR libstdc++/88113 | ||||||
|  | 	* src/c++17/memory_resource.cc (bitset::size_type): Use the smaller | ||||||
|  | 	of uint32_t and size_t. | ||||||
|  | 	(bitset::size(), bitset::free(), bitset::update_next_word()) | ||||||
|  | 	(bitset::max_blocks_per_chunk(), bitset::max_word_index()): Use | ||||||
|  | 	size_type consistently instead of size_t. | ||||||
|  | 	(chunk): Adjust static_assert checking sizeof(chunk). | ||||||
|  | 
 | ||||||
| 2018-11-20  Ville Voutilainen  <ville.voutilainen@gmail.com> | 2018-11-20  Ville Voutilainen  <ville.voutilainen@gmail.com> | ||||||
| 
 | 
 | ||||||
| 	Housekeeping for the effective targets of optional's tests. | 	Housekeeping for the effective targets of optional's tests. | ||||||
|  |  | ||||||
|  | @ -252,11 +252,13 @@ namespace pmr | ||||||
| 
 | 
 | ||||||
|   namespace { |   namespace { | ||||||
| 
 | 
 | ||||||
|   // Simple bitset with runtime size. Tracks used blocks in a pooled chunk.
 |   // Simple bitset with runtime size.
 | ||||||
|  |   // Tracks which blocks in a pool chunk are used/unused.
 | ||||||
|   struct bitset |   struct bitset | ||||||
|   { |   { | ||||||
|     using word = uint64_t; |     using word = uint64_t; | ||||||
|     using size_type = uint32_t; |     using size_type // unsigned integer type with no more than 32 bits
 | ||||||
|  |       = conditional_t<numeric_limits<size_t>::digits <= 32, size_t, uint32_t>; | ||||||
| 
 | 
 | ||||||
|     static constexpr unsigned bits_per_word = numeric_limits<word>::digits; |     static constexpr unsigned bits_per_word = numeric_limits<word>::digits; | ||||||
| 
 | 
 | ||||||
|  | @ -269,7 +271,7 @@ namespace pmr | ||||||
|       __builtin_memset(_M_words, 0, last_word * sizeof(*_M_words)); |       __builtin_memset(_M_words, 0, last_word * sizeof(*_M_words)); | ||||||
|       // Set bits beyond _M_size, so they are not treated as free blocks:
 |       // Set bits beyond _M_size, so they are not treated as free blocks:
 | ||||||
|       if (const size_type extra_bits = num_blocks % bits_per_word) |       if (const size_type extra_bits = num_blocks % bits_per_word) | ||||||
| 	_M_words[last_word] = (word)-1 << extra_bits; | 	_M_words[last_word] = word(-1) << extra_bits; | ||||||
|       __glibcxx_assert( empty() ); |       __glibcxx_assert( empty() ); | ||||||
|       __glibcxx_assert( free() == num_blocks ); |       __glibcxx_assert( free() == num_blocks ); | ||||||
|     } |     } | ||||||
|  | @ -278,12 +280,12 @@ namespace pmr | ||||||
|     ~bitset() = default; |     ~bitset() = default; | ||||||
| 
 | 
 | ||||||
|     // Number of blocks
 |     // Number of blocks
 | ||||||
|     size_t size() const noexcept { return _M_size; } |     size_type size() const noexcept { return _M_size; } | ||||||
| 
 | 
 | ||||||
|     // Number of free blocks (unset bits)
 |     // Number of free blocks (unset bits)
 | ||||||
|     size_t free() const noexcept |     size_type free() const noexcept | ||||||
|     { |     { | ||||||
|       size_t n = 0; |       size_type n = 0; | ||||||
|       for (size_type i = _M_next_word; i < nwords(); ++i) |       for (size_type i = _M_next_word; i < nwords(); ++i) | ||||||
| 	n += (bits_per_word - std::__popcount(_M_words[i])); | 	n += (bits_per_word - std::__popcount(_M_words[i])); | ||||||
|       return n; |       return n; | ||||||
|  | @ -376,7 +378,7 @@ namespace pmr | ||||||
|     // this function saturates _M_next_word at max_word_index().
 |     // this function saturates _M_next_word at max_word_index().
 | ||||||
|     void update_next_word() noexcept |     void update_next_word() noexcept | ||||||
|     { |     { | ||||||
|       size_t next = _M_next_word; |       size_type next = _M_next_word; | ||||||
|       while (_M_words[next] == word(-1) && ++next < nwords()) |       while (_M_words[next] == word(-1) && ++next < nwords()) | ||||||
| 	{ } | 	{ } | ||||||
|       _M_next_word = std::min(next, max_word_index()); |       _M_next_word = std::min(next, max_word_index()); | ||||||
|  | @ -397,11 +399,11 @@ namespace pmr | ||||||
|     { return (_M_size + bits_per_word - 1) / bits_per_word; } |     { return (_M_size + bits_per_word - 1) / bits_per_word; } | ||||||
| 
 | 
 | ||||||
|     // Maximum value that can be stored in bitset::_M_size member (approx 500k)
 |     // Maximum value that can be stored in bitset::_M_size member (approx 500k)
 | ||||||
|     static constexpr size_t max_blocks_per_chunk() noexcept |     static constexpr size_type max_blocks_per_chunk() noexcept | ||||||
|     { return (1ull << _S_size_digits) - 1; } |     { return (size_type(1) << _S_size_digits) - 1; } | ||||||
| 
 | 
 | ||||||
|     // Maximum value that can be stored in bitset::_M_next_word member (8191).
 |     // Maximum value that can be stored in bitset::_M_next_word member (8191).
 | ||||||
|     static constexpr size_t max_word_index() noexcept |     static constexpr size_type max_word_index() noexcept | ||||||
|     { return (max_blocks_per_chunk() + bits_per_word - 1) / bits_per_word; } |     { return (max_blocks_per_chunk() + bits_per_word - 1) / bits_per_word; } | ||||||
| 
 | 
 | ||||||
|     word* data() const noexcept { return _M_words; } |     word* data() const noexcept { return _M_words; } | ||||||
|  | @ -519,9 +521,12 @@ namespace pmr | ||||||
|     { return std::less<const void*>{}(p, c._M_p); } |     { return std::less<const void*>{}(p, c._M_p); } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // For 64-bit this is 3*sizeof(void*) and for 32-bit it's 4*sizeof(void*).
 |   // For 64-bit pointers this is the size of three pointers i.e. 24 bytes.
 | ||||||
|  |   // For 32-bit and 20-bit pointers it's four pointers (16 bytes).
 | ||||||
|  |   // For 16-bit pointers it's five pointers (10 bytes).
 | ||||||
|   // TODO pad 64-bit to 4*sizeof(void*) to avoid splitting across cache lines?
 |   // TODO pad 64-bit to 4*sizeof(void*) to avoid splitting across cache lines?
 | ||||||
|   static_assert(sizeof(chunk) == 2 * sizeof(uint32_t) + 2 * sizeof(void*)); |   static_assert(sizeof(chunk) | ||||||
|  |       == sizeof(bitset::size_type) + sizeof(uint32_t) + 2 * sizeof(void*)); | ||||||
| 
 | 
 | ||||||
|   // An oversized allocation that doesn't fit in a pool.
 |   // An oversized allocation that doesn't fit in a pool.
 | ||||||
|   struct big_block |   struct big_block | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Jonathan Wakely
						Jonathan Wakely