Some further testing shows that cppcheck oddly has the same behavior as gcc with this particular warning. It emits a warning for the direct code, but not for the macro expansion. It doesn't do this for other types of warnings either such as divide by 0.
And yes, clang does emit the warning but it's a slightly different one: warning: result of comparison of constant -50 with expression of type
'volatile uint16_t' (aka 'volatile unsigned short') is always false [-Wtautological-constant-out-of-range-compare]
Note that the compiled code may lead to "incorrect" behavior (at least according to what's very likely intended by the programmer), so ignoring the warning or not getting any can be pretty bad, as it will follow arithmetic conversion as defined in the C standard.
In the OP's particular example, it should behave as expected (and thus be always false), as the rank of the unsigned integer uint16_t is less than that of the negative constant (which is of type int), so in this case, the uint16_t integer will get promoted to int (which can hold all values of uint16_t) and both will be compared and be always false as expected.
OTOH, if the unsigned integer had the same rank as int (so, unsigned int instead of uint16_t, for instance), then the constant -50 would get converted to unsigned int and thus would be converted into a large unsigned value, which would probably not do what you expect at all.
Cf. the "Usual arithmetic conversions" section in the C std.
And indeed... if you replace 'uint16_t v' with 'unsigned int v' in your struct definition, you get your warning back with the macro expansion. So they have likely considered that this latter case is much more severe than the former, as it can lead to incorrect behavior rather than just being always false (as expected), and so this warranted a warning more so than the former case, which in effect is just 'dead code'.