Skip to content

Commit f3eff99

Browse files
authored
vector_algorithms.cpp: avoid unaligned access (#5760)
1 parent 9ba4a22 commit f3eff99

File tree

1 file changed

+34
-24
lines changed

1 file changed

+34
-24
lines changed

stl/src/vector_algorithms.cpp

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -111,30 +111,34 @@ __declspec(noalias) void __cdecl __std_swap_ranges_trivially_swappable_noalias(
111111
} while (_First1 != _Stop_at);
112112
}
113113

114-
#if defined(_M_X64) // NOTE: UNALIGNED MEMORY ACCESSES
114+
#if defined(_M_X64)
115115
constexpr size_t _Mask_8 = ~((static_cast<size_t>(1) << 3) - 1);
116116
if (_Byte_length(_First1, _Last1) >= 8) {
117117
const void* _Stop_at = _First1;
118118
_Advance_bytes(_Stop_at, _Byte_length(_First1, _Last1) & _Mask_8);
119119
do {
120-
const unsigned long long _Left = *static_cast<unsigned long long*>(_First1);
121-
const unsigned long long _Right = *static_cast<unsigned long long*>(_First2);
122-
*static_cast<unsigned long long*>(_First1) = _Right;
123-
*static_cast<unsigned long long*>(_First2) = _Left;
120+
unsigned long long _Left;
121+
unsigned long long _Right;
122+
memcpy(&_Left, _First1, 8);
123+
memcpy(&_Right, _First2, 8);
124+
memcpy(_First1, &_Right, 8);
125+
memcpy(_First2, &_Left, 8);
124126
_Advance_bytes(_First1, 8);
125127
_Advance_bytes(_First2, 8);
126128
} while (_First1 != _Stop_at);
127129
}
128-
#elif defined(_M_IX86) // NOTE: UNALIGNED MEMORY ACCESSES
130+
#elif defined(_M_IX86)
129131
constexpr size_t _Mask_4 = ~((static_cast<size_t>(1) << 2) - 1);
130132
if (_Byte_length(_First1, _Last1) >= 4) {
131133
const void* _Stop_at = _First1;
132134
_Advance_bytes(_Stop_at, _Byte_length(_First1, _Last1) & _Mask_4);
133135
do {
134-
const unsigned long _Left = *static_cast<unsigned long*>(_First1);
135-
const unsigned long _Right = *static_cast<unsigned long*>(_First2);
136-
*static_cast<unsigned long*>(_First1) = _Right;
137-
*static_cast<unsigned long*>(_First2) = _Left;
136+
unsigned long _Left;
137+
unsigned long _Right;
138+
memcpy(&_Left, _First1, 4);
139+
memcpy(&_Right, _First2, 4);
140+
memcpy(_First1, &_Right, 4);
141+
memcpy(_First2, &_Left, 4);
138142
_Advance_bytes(_First1, 4);
139143
_Advance_bytes(_First2, 4);
140144
} while (_First1 != _Stop_at);
@@ -202,35 +206,41 @@ namespace {
202206
} while (_First1 != _Stop_at);
203207
}
204208

205-
#if defined(_M_X64) // NOTE: UNALIGNED MEMORY ACCESSES
209+
#if defined(_M_X64)
206210
constexpr size_t _Mask_8 = ~((static_cast<size_t>(1) << 3) - 1);
207211
if (_Byte_length(_First1, _Last1) >= 8) {
208212
const void* _Stop_at = _First1;
209213
_Advance_bytes(_Stop_at, _Byte_length(_First1, _Last1) & _Mask_8);
210214
do {
211-
const unsigned long long _Val1 = *static_cast<unsigned long long*>(_First1);
212-
const unsigned long long _Val2 = *static_cast<unsigned long long*>(_First2);
213-
const unsigned long long _Val3 = *static_cast<unsigned long long*>(_First3);
214-
*static_cast<unsigned long long*>(_First1) = _Val2;
215-
*static_cast<unsigned long long*>(_First2) = _Val3;
216-
*static_cast<unsigned long long*>(_First3) = _Val1;
215+
unsigned long long _Val1;
216+
unsigned long long _Val2;
217+
unsigned long long _Val3;
218+
memcpy(&_Val1, _First1, 8);
219+
memcpy(&_Val2, _First2, 8);
220+
memcpy(&_Val3, _First3, 8);
221+
memcpy(_First1, &_Val2, 8);
222+
memcpy(_First2, &_Val3, 8);
223+
memcpy(_First3, &_Val1, 8);
217224
_Advance_bytes(_First1, 8);
218225
_Advance_bytes(_First2, 8);
219226
_Advance_bytes(_First3, 8);
220227
} while (_First1 != _Stop_at);
221228
}
222-
#elif defined(_M_IX86) // NOTE: UNALIGNED MEMORY ACCESSES
229+
#elif defined(_M_IX86)
223230
constexpr size_t _Mask_4 = ~((static_cast<size_t>(1) << 2) - 1);
224231
if (_Byte_length(_First1, _Last1) >= 4) {
225232
const void* _Stop_at = _First1;
226233
_Advance_bytes(_Stop_at, _Byte_length(_First1, _Last1) & _Mask_4);
227234
do {
228-
const unsigned long _Val1 = *static_cast<unsigned long*>(_First1);
229-
const unsigned long _Val2 = *static_cast<unsigned long*>(_First2);
230-
const unsigned long _Val3 = *static_cast<unsigned long*>(_First3);
231-
*static_cast<unsigned long*>(_First1) = _Val2;
232-
*static_cast<unsigned long*>(_First2) = _Val3;
233-
*static_cast<unsigned long*>(_First3) = _Val1;
235+
unsigned long _Val1;
236+
unsigned long _Val2;
237+
unsigned long _Val3;
238+
memcpy(&_Val1, _First1, 4);
239+
memcpy(&_Val2, _First2, 4);
240+
memcpy(&_Val3, _First3, 4);
241+
memcpy(_First1, &_Val2, 4);
242+
memcpy(_First2, &_Val3, 4);
243+
memcpy(_First3, &_Val1, 4);
234244
_Advance_bytes(_First1, 4);
235245
_Advance_bytes(_First2, 4);
236246
_Advance_bytes(_First3, 4);

0 commit comments

Comments
 (0)