Skip to content

Commit d584663

Browse files
committed
Update can_helpers to remove UB
1 parent e604fb1 commit d584663

File tree

1 file changed

+18
-27
lines changed

1 file changed

+18
-27
lines changed

src/can_helpers.hpp

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,43 @@
11
#pragma once
22

3-
#include <string.h>
43
#include <stdint.h>
4+
#include <string.h>
55

6-
template <typename T>
6+
7+
template<typename T>
78
T can_get_signal_raw(const uint8_t* buf, const size_t startBit, const size_t length, const bool isIntel) {
89
constexpr int N = 8;
910

10-
union {
11-
uint64_t tempVal;
12-
uint8_t tempBuf[N]; // This is used because memcpy into tempVal generates less optimal code
13-
T retVal;
14-
};
15-
1611
const uint64_t mask = length < 64 ? (1ULL << length) - 1ULL : -1ULL;
1712
const uint8_t shift = isIntel ? startBit : (64 - startBit) - length;
1813

19-
memcpy(tempBuf, buf, N);
14+
uint64_t tempVal = 0;
15+
memcpy(&tempVal, buf, N);
2016
if (isIntel) {
2117
tempVal = (tempVal >> shift) & mask;
2218
} else {
2319
tempVal = __builtin_bswap64(tempVal);
2420
tempVal = (tempVal >> shift) & mask;
2521
}
2622

23+
T retVal;
24+
memcpy(&retVal, &tempVal, sizeof(T));
25+
2726
return retVal;
2827
}
2928

30-
template <typename T>
29+
template<typename T>
3130
void can_set_signal_raw(uint8_t* buf, const T val, const size_t startBit, const size_t length, const bool isIntel) {
3231
constexpr int N = 8;
3332

3433
const uint64_t mask = length < 64 ? (1ULL << length) - 1ULL : -1ULL;
3534
const uint8_t shift = isIntel ? startBit : (64 - startBit) - length;
3635

37-
union {
38-
uint64_t valAsBits;
39-
T tempVal;
40-
};
41-
42-
tempVal = val;
43-
44-
union {
45-
uint64_t data;
46-
uint8_t tempBuf[N];
47-
};
36+
uint64_t valAsBits = 0;
37+
memcpy(&valAsBits, &val, sizeof(T));
4838

49-
memcpy(tempBuf, buf, N);
39+
uint64_t data = 0;
40+
memcpy(&data, buf, N);
5041
if (isIntel) {
5142
data &= ~(mask << shift);
5243
data |= valAsBits << shift;
@@ -57,10 +48,10 @@ void can_set_signal_raw(uint8_t* buf, const T val, const size_t startBit, const
5748
data = __builtin_bswap64(data);
5849
}
5950

60-
memcpy(buf, tempBuf, N);
51+
memcpy(buf, &data, N);
6152
}
6253

63-
template <typename T>
54+
template<typename T>
6455
float can_get_signal_raw(
6556
const uint8_t* buf,
6657
const size_t startBit,
@@ -73,7 +64,7 @@ float can_get_signal_raw(
7364
return (retVal * factor) + offset;
7465
}
7566

76-
template <typename T>
67+
template<typename T>
7768
constexpr void can_set_signal_raw(
7869
uint8_t* buf,
7970
const float val,
@@ -87,12 +78,12 @@ constexpr void can_set_signal_raw(
8778
can_set_signal_raw<T>(buf, scaledVal, startBit, length, isIntel);
8879
}
8980

90-
template <typename T, typename TMsg>
81+
template<typename T, typename TMsg>
9182
constexpr T can_get_signal(const TMsg& msg, const size_t startBit, const size_t length, const bool isIntel) {
9283
return can_get_signal_raw<T>(can_msg_get_payload(msg).data(), startBit, length, isIntel);
9384
}
9485

95-
template <typename T, typename TMsg>
86+
template<typename T, typename TMsg>
9687
constexpr void can_set_signal(TMsg& msg, const T val, const size_t startBit, const size_t length, const bool isIntel) {
9788
can_set_signal_raw<T>(can_msg_get_payload(msg).data(), val, startBit, length, isIntel);
9889
}

0 commit comments

Comments
 (0)