LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 38789 - warnings for untaken branch of ?: expression, at file scope
Summary: warnings for untaken branch of ?: expression, at file scope
Status: NEW
Alias: None
Product: clang
Classification: Unclassified
Component: Frontend (show other bugs)
Version: unspecified
Hardware: PC Linux
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks: 4068
  Show dependency tree
 
Reported: 2018-08-31 05:19 PDT by Arnd Bergmann
Modified: 2019-07-21 00:15 PDT (History)
7 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arnd Bergmann 2018-08-31 05:19:45 PDT
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
Comment 1 Arnd Bergmann 2018-08-31 07:51:54 PDT
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,    \
...
Comment 2 Richard Smith 2018-08-31 16:23:19 PDT
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.
Comment 3 Nick Desaulniers 2019-07-21 00:15:46 PDT
Patch: https://reviews.llvm.org/D63889