I have encountered a couple of warnings in the Linux kernel for range checking of shift counts. The common macro #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) produces a warning at file scope for a '64' argument, but not inside of a function. I tried using __builtin_choose_expr() to avoid that, which made it worse: that version always warns, regardless of the scope (it also does this with gcc). The same thing happened with a less common macro, which I've simplifed into 'COND_BIT()' in the test case below. The behavior is the same for all clang versions I tried (3.8 through 8), but my expectation was to see no warning at all. $ clang-8 -Wall -O2 -c -xc - << EOF #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #define DMA_BIT_MASK_2(n) __builtin_choose_expr((n) == 64, ~0ULL, (1ULL<<(n))-1) #define COND_BIT(x) (((x) >= 0) ? (1ul << x) : 0ul) #define COND_BIT_2(x) __builtin_choose_expr(x >= 0, 1ul << x, 0ul) // warning: shift count >= width of type [-Wshift-count-overflow] long long a = DMA_BIT_MASK(64); // warning: shift count >= width of type [-Wshift-count-overflow] long long b = DMA_BIT_MASK_2(64); // warning: shift count is negative [-Wshift-count-negative] // [gcc: no warning] unsigned long c = COND_BIT(-1); // warning: shift count is negative [-Wshift-count-negative] unsigned long d = COND_BIT_2(-1); int f(void) { // no warning long long a = DMA_BIT_MASK(64); // warning: shift count >= width of type [-Wshift-count-overflow] long long b = DMA_BIT_MASK_2(64); // no warning unsigned long c = COND_BIT(-1); // warning: shift count is negative [-Wshift-count-negative] unsigned long d = COND_BIT_2(-1); // prevent unused variable wanings return a & b & c & d; } EOF
Another related warning appears with division by zero in an expression assigned to a global variable: #define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ ... \ .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ ...
This is a general problem with DiagRuntimeBehavior: it works by building a CFG of the enclosing function and checking if the expression is reachable within that CFG; we give up and just emit the diagnostic if there isn't an enclosing function. We should probably rearrange how we handle it to apply at the end of any Expr/Stmt region, not just functions.
Patch: https://reviews.llvm.org/D63889