From: Thomas Weißschuh <thomas@xxxxxxxx> During the expansion of shifts, the variable 'conservative' is used to inhibit any possible diagnostics (for example, because he needed information is if the expression is a constant or not). However, this must not inhibit the simplification of valid shift expressions. Unfortunately, by moving the validation inside check_shift_count(), this what was done by commit 0b73dee01 ("big-shift: move the check into check_shift_count()"). Found through a false positive VLA detected in the Linux kernel. The array size was computed through min() on a shifted constant value and sparse complained about it. Fix this by returning early (and thus avoiding possible diagnostics *and* simplification) if 'conservative' is set only if the shift count is invalid. Fixes: 0b73dee0171a15800d0a4ae6225b602bf8961599 Signed-off-by: Thomas Weißschuh <thomas@xxxxxxxx> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- expand.c | 2 +- validation/simplify-binops.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 validation/simplify-binops.c diff --git a/expand.c b/expand.c index e8e50b080..7936e29cb 100644 --- a/expand.c +++ b/expand.c @@ -197,7 +197,7 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype) return 0; r = right->value; if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) { - if (conservative) + if (conservative && left->type != EXPR_VALUE) return 0; check_shift_count(expr, right); } diff --git a/validation/simplify-binops.c b/validation/simplify-binops.c new file mode 100644 index 000000000..e464c37ac --- /dev/null +++ b/validation/simplify-binops.c @@ -0,0 +1,12 @@ +#define __is_constexpr(x) \ + (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) + +static void test(int x) { + static int b[] = { + [__builtin_choose_expr(__is_constexpr(1 << 1), 1, x)] = 0, + }; +} + +/* + * check-name: simplify-binops + */ -- 2.21.0