@@ -889,10 +889,8 @@ static struct symbol *evaluate_logical(struct expression *expr)
/* the result is int [6.5.13(3), 6.5.14(3)] */
expr->ctype = &int_ctype;
- if (expr->flags) {
- if (!(expr->left->flags & expr->right->flags & CEF_ICE))
- expr->flags = CEF_NONE;
- }
+ expr->flags = expr->left->flags & expr->right->flags;
+ expr->flags &= ~CEF_CONST_MASK;
return &int_ctype;
}
@@ -903,13 +901,11 @@ static struct symbol *evaluate_binop(struct expression *expr)
int rclass = classify_type(expr->right->ctype, &rtype);
int op = expr->op;
- if (expr->flags) {
- if (!(expr->left->flags & expr->right->flags & CEF_ICE))
- expr->flags = CEF_NONE;
- }
-
/* number op number */
if (lclass & rclass & TYPE_NUM) {
+ expr->flags = expr->left->flags & expr->right->flags;
+ expr->flags &= ~CEF_CONST_MASK;
+
if ((lclass | rclass) & TYPE_FLOAT) {
switch (op) {
case '+': case '-': case '*': case '/':
@@ -1010,10 +1006,7 @@ static struct symbol *evaluate_compare(struct expression *expr)
struct symbol *ctype;
const char *typediff;
- if (expr->flags) {
- if (!(expr->left->flags & expr->right->flags & CEF_ICE))
- expr->flags = CEF_NONE;
- }
+ expr->flags = left->flags & right->flags & ~CEF_CONST_MASK;
/* Type types? */
if (is_type_type(ltype) && is_type_type(rtype))
@@ -146,7 +146,6 @@ static struct token *builtin_types_compatible_p_expr(struct token *token,
{
struct expression *expr = alloc_expression(
token->pos, EXPR_COMPARE);
- expr->flags = CEF_SET_ICE;
expr->op = SPECIAL_EQUAL;
token = token->next;
if (!match_op(token, '('))
@@ -758,8 +757,6 @@ static struct token *cast_expression(struct token *token, struct expression **tr
sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op)); \
break; \
} \
- top->flags = left->flags & right->flags \
- & ~CEF_CONST_MASK; \
top->op = op; \
top->left = left; \
top->right = right; \
new file mode 100644
@@ -0,0 +1,33 @@
+static int a[] = {
+ [0 + 0] = 0, // OK
+ [0 + 0.] = 0, // KO
+ [(void*)0 + 0] = 0, // KO
+ [0 + __builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [0 + __builtin_choose_expr(0, 0., 0)] = 0, // OK
+ [0 + __builtin_choose_expr(0, 0, 0.)] = 0, // KO
+ [0 < 0] = 0, // OK
+ [0 < 0.] = 0, // KO
+ [0 < __builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [0 < __builtin_choose_expr(0, 0., 0)] = 0, // OK
+ [0 < __builtin_choose_expr(0, 0, 0.)] = 0, // KO
+ [0 && 0] = 0, // OK
+ [0 && 0.] = 0, // KO
+ [0 && __builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [0 && __builtin_choose_expr(0, 0., 0)] = 0, // OK
+ [0 && __builtin_choose_expr(0, 0, 0.)] = 0, // KO
+ [0 + __builtin_types_compatible_p(int, float)] = 0, // OK
+};
+
+/*
+ * check-name: Expression constness propagation in binops and alike
+ *
+ * check-error-start
+constexpr-binop.c:3:12: error: bad constant expression
+constexpr-binop.c:4:19: error: bad integer constant expression
+constexpr-binop.c:7:12: error: bad constant expression
+constexpr-binop.c:9:12: error: bad integer constant expression
+constexpr-binop.c:12:12: error: bad integer constant expression
+constexpr-binop.c:14:12: error: bad integer constant expression
+constexpr-binop.c:17:12: error: bad integer constant expression
+ * check-error-end
+ */