mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Add assertions for dangerous bit shift that could trigger undefined
behaviour Change-Id: I051ed229d407eafcae1ea4b5fc745176a751e036
This commit is contained in:
@@ -1,10 +1,17 @@
|
||||
/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
long long __aeabi_llsl(long long value, int shift) {
|
||||
uint32_t low = (uint32_t)value << shift;
|
||||
/* "Shift behavior is undefined if the right operand is negative, or greater
|
||||
* than or equal to the length in bits of the promoted left operand" according
|
||||
* to C++ spec. However, arm compiler fill the vacated bits with 0 */
|
||||
assert(shift < 32 || low == 0);
|
||||
uint32_t high = ((uint32_t)(value >> 32) << shift);
|
||||
// Same comment
|
||||
assert(shift < 32 || high == 0);
|
||||
if (shift < 32) {
|
||||
high |= ((uint32_t)value >> (32 - shift));
|
||||
} else {
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
long long __aeabi_llsr(long long value, int shift) {
|
||||
uint32_t low = ((uint32_t)value >> shift);
|
||||
/* "Shift behavior is undefined if the right operand is negative, or greater
|
||||
* than or equal to the length in bits of the promoted left operand" according
|
||||
* to C++ spec. However, arm compiler fill the vacated bits with 0 */
|
||||
assert(shift < 32 || low == 0);
|
||||
if (shift < 32) {
|
||||
low |= ((uint32_t)(value >> 32) << (32 - shift));
|
||||
} else {
|
||||
low |= ((uint32_t)(value >> 32) >> (shift - 32));
|
||||
}
|
||||
uint32_t high = (uint32_t)(value >> 32) >> shift;
|
||||
// Same comment
|
||||
assert(shift < 32 || high == 0);
|
||||
return ((long long)high << 32) | low;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user