From: Nicolai Stange <nicstange@xxxxxxxxx> Move the whole calculation of conditional expressions' constness flags to the evaluation phase such that expressions like 0 ? __builtin_choose_expr(0, 0, 0) : 0 0 ? 0 : __builtin_choose_expr(0, 0, 0) can now be recognized as qualifying as integer constant expressions. Signed-off-by: Nicolai Stange <nicstange@xxxxxxxxx> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 8 ++------ expression.c | 6 ------ validation/constexpr-conditional.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 validation/constexpr-conditional.c diff --git a/evaluate.c b/evaluate.c index 07788eacc..6d6e462cd 100644 --- a/evaluate.c +++ b/evaluate.c @@ -1122,12 +1122,8 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr) true = &expr->cond_true; } - if (expr->flags) { - int flags = expr->conditional->flags & CEF_ICE; - flags &= (*true)->flags & expr->cond_false->flags; - if (!flags) - expr->flags = CEF_NONE; - } + expr->flags = (expr->conditional->flags & (*true)->flags & + expr->cond_false->flags & ~CEF_CONST_MASK); lclass = classify_type(ltype, <ype); rclass = classify_type(rtype, &rtype); diff --git a/expression.c b/expression.c index 0332c4406..7f1eff306 100644 --- a/expression.c +++ b/expression.c @@ -856,12 +856,6 @@ struct token *conditional_expression(struct token *token, struct expression **tr token = parse_expression(token->next, &expr->cond_true); token = expect(token, ':', "in conditional expression"); token = conditional_expression(token, &expr->cond_false); - if (expr->left && expr->cond_false) { - expr->flags = expr->left->flags & expr->cond_false->flags; - if (expr->cond_true) - expr->flags &= expr->cond_true->flags; - expr->flags &= ~CEF_CONST_MASK; - } } return token; } diff --git a/validation/constexpr-conditional.c b/validation/constexpr-conditional.c new file mode 100644 index 000000000..a3331b3ef --- /dev/null +++ b/validation/constexpr-conditional.c @@ -0,0 +1,34 @@ +static int a[] = { + [0 ? : 0] = 0, // OK + [1 ? : 0] = 0, // OK + [0 ? 0 : 0] = 0, // OK + [1 ? 0 : 0] = 0, // OK + [0 ? 0 : __builtin_choose_expr(0, 0, 0)] = 0, // OK + [1 ? __builtin_choose_expr(0, 0, 0) : 0] = 0, // OK + [0 ? __builtin_choose_expr(0, 0, 0) : 0] = 0, // OK + [1 ? 1 : __builtin_choose_expr(0, 0, 0)] = 0, // OK + [__builtin_choose_expr(0, 0, 0) ? : 0] = 0, // OK + [__builtin_choose_expr(0, 0, 1) ? : 0] = 0, // OK + [0. ? : 0] = 0, // KO + [0 ? 0. : 0] = 0, // KO + [1 ? : 0.] = 0, // KO + [__builtin_choose_expr(0, 0., 0) ? : 0] = 0, // OK + [__builtin_choose_expr(0, 0, 0.) ? : 0] = 0, // KO + [0 ? __builtin_choose_expr(0, 0., 0) : 0] = 0, // OK + [0 ? __builtin_choose_expr(0, 0, 0.) : 0] = 0, // KO + [1 ? 0 : __builtin_choose_expr(0, 0., 0)] = 0, // OK + [1 ? 0 : __builtin_choose_expr(0, 0, 0.)] = 0, // KO +}; + +/* + * check-name: Expression constness propagation in conditional expressions + * + * check-error-start +constexpr-conditional.c:12:13: error: bad constant expression +constexpr-conditional.c:13:19: error: bad constant expression +constexpr-conditional.c:14:12: error: bad constant expression +constexpr-conditional.c:16:42: error: bad constant expression +constexpr-conditional.c:18:48: error: bad constant expression +constexpr-conditional.c:20:14: error: bad constant expression + * check-error-end + */ -- 2.12.0 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html