Rule in question: c:S836
SonarQube warning: The result of the right shift is undefined due to shifting by '8', which is greater or equal to the width of type 'uint16_t'
SonarQube Server: 9.2.4
SonarScanner 4.6.2.2472
TI Code Composer 9.0.1
Relevant code snippets:
#include <stdint.h>
typedef enum
{
GRPID_1 = 1,
GRPID_2,
GRPID_3,
GRPID_4,
GRPID_5,
GRPID_6,
GRPID_7,
GRPID_8,
GRPID_9,
GRPID_10,
GRPID_11,
GRPID_12,
GRPID_13,
GRPID_14
} SCI_GROUP_ID_t;
typedef struct
{
const SCI_GROUP_ID_t groupID;
const uint16_t groupSize;
bool isOnDemand;
const uint16_t minUpdateTime;
uint32_t sequenceNum;
uint32_t *pTimer;
uint8_t *pPayload;
} Group_info_t;
typedef struct
{
uint8_t bytes[40];
} sci_group_header_t;
sci_group_header_t grp_header_buf;
static Group_info_t Group_info[20]
Initial iteration of code that raised the error:
grp_header_buf.bytes[4] = (uint8_t) ((Group_info[index].groupID >> 8) & 0x00FF);
Updated code to try to resolve the error by casting explicitly:
grp_header_buf.bytes[4] = (uint8_t) (((uint16_t) Group_info[index].groupID >> 8) & 0x00FF);
Note: uint32/16/8 types are TI-defined in their <stdint.h> header file. On the TI TMS320C architecture, the smallest memory-based size you can get is a 16-bit value.
The field in question has been cast to a uint16_t prior to being shifted, which per operator precedence table, the cast should happen prior to the shift.
However, even adding the explicit cast in the second code sample to uint16_t was not enough to get rid of the warning. Also important here is that the Group_info.groupID
field is technically an enumeration, and thus what I saw as the need to explicitly cast to a strict type for this shifting.
I am asking the developer whose code this is to make the following modification (adding parentheses around the cast and the variable being cast) to see if it resolves the warning, but if it does, that seems like a parser issue if the cast is not being handled before the shifting. Based on that experiment I will add to this thread with the results.
grp_header_buf.bytes[4] = (uint8_t) ((((uint16_t) Group_info[index].groupID) >> 8) & 0x00FF);