The result of a shift operation on a constants by a constant value is also constant. 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. Signed-off-by: Thomas Weißschuh <thomas@xxxxxxxx> --- 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 e8e50b0..7936e29 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 0000000..e464c37 --- /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