Second question:
How to make code compatible with MISRA C: 2004?
You can write this according to MISRA as follows:
typedef unsigned int UNS_32; UNS_32 test(void); UNS_32 test(void) { UNS_32 original_arg = 3U; UNS_32 irq_source = 1UL << original_arg; return irq_source; }
Back to the first question:
What's going on here?
The first rule 10.3 states that complex integer expressions must not be cast to a type wider than the base type.
One key to understanding the error message is the basic concept type, which is the MISRA-C concept. In short, the basic type of a constant is the smallest type into which it can fit. In this case, 1U has the base type unsigned char , despite the fact that it has the language type unsigned int .
The rationale for rule 10.3 is to avoid cases where the result of an operation is used in a context that is larger than the parts. A standard example of this is multiplication, where alpha and beta are 16-bit types:
uint32_t res = alpha * beta;
Here, if int is 16 bits, the multiplication will be done in 16 bits, the result will be converted to 32 bits. On the other hand, if int is 32 bits or more, multiplication will be performed with greater precision. Specifically, this will cause the result to be different when multiplied, say, 0x4000 and 0x10.
MISRA Rule 10.3 allowed this by establishing that the casting result is placed in a temporary cast, which is later converted to a larger type. Thus, you are forced to write code anyway.
If you intend to use 16-bit multiplication:
uint16_t tmp = alpha * beta; uint32_t res = tmp;
On the other hand, if the intention is a 32-bit multiplication:
UNS_32 res = (UNS_32)alpha * (UNS_32)beta;
So, in this case, the expression 1U << count is a potential problem. If converted_arg greater than 16 bits, this may lead to a problem when using 16-bit int s. However, MISRA allows you to write 1UL << count or (UNS_32)((UNS_32)1U << original_arg) . You mentioned that in the latter case, MISRA checker issued an error - mine is wrong, please check again.
So, as I see it, the MISRA C validator that you used correctly identified a violation of rule 10.3.