@@ -1805,8 +1805,8 @@ static struct symbol *evaluate_sign(struct expression *expr)
{
struct symbol *ctype = expr->unop->ctype;
int class = classify_type(ctype, &ctype);
- if (expr->flags && !(expr->unop->flags & CEF_ICE))
- expr->flags = CEF_NONE;
+ unsigned char flags = expr->unop->flags & ~CEF_CONST_MASK;
+
/* should be an arithmetic type */
if (!(class & TYPE_NUM))
return bad_expr_type(expr);
@@ -1823,6 +1823,7 @@ Normal:
}
if (expr->op == '+')
*expr = *expr->unop;
+ expr->flags = flags;
expr->ctype = ctype;
return ctype;
Restr:
@@ -1860,8 +1861,7 @@ static struct symbol *evaluate_preop(struct expression *expr)
return evaluate_postop(expr);
case '!':
- if (expr->flags && !(expr->unop->flags & CEF_ICE))
- expr->flags = CEF_NONE;
+ expr->flags = expr->unop->flags & ~CEF_CONST_MASK;
if (is_safe_type(ctype))
warning(expr->pos, "testing a 'safe expression'");
if (is_float_type(ctype)) {
@@ -450,8 +450,6 @@ struct token *primary_expression(struct token *token, struct expression **tree)
expr = alloc_expression(token->pos, EXPR_PREOP);
expr->op = '(';
token = parens_expression(token, &expr->unop, "in expression");
- if (expr->unop)
- expr->flags = expr->unop->flags;
break;
}
if (token->special == '[' && lookup_type(token->next)) {
@@ -663,7 +661,6 @@ static struct token *unary_expression(struct token *token, struct expression **t
unary = alloc_expression(token->pos, EXPR_PREOP);
unary->op = token->special;
unary->unop = unop;
- unary->flags = unop->flags & ~CEF_CONST_MASK;
*tree = unary;
return next;
}
new file mode 100644
@@ -0,0 +1,29 @@
+static int a[] = {
+ [+0] = 0, // OK
+ [+__builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [+0.] = 0, // KO
+ [+__builtin_choose_expr(0, 0, 0.)] = 0, // KO
+ [-0] = 0, // OK
+ [-__builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [-0.] = 0, // KO
+ [-__builtin_choose_expr(0, 0, 0.)] = 0, // KO
+ [~0] = 0, // OK
+ [~__builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [!0] = 0, // OK
+ [!__builtin_choose_expr(0, 0, 0)] = 0, // OK
+ [!0.] = 0, // KO
+ [!__builtin_choose_expr(0, 0, 0.)] = 0, // KO
+};
+
+/*
+ * check-name: Expression constness propagation in preops
+ *
+ * check-error-start
+constexpr-preop.c:4:5: error: bad constant expression
+constexpr-preop.c:5:33: error: bad constant expression
+constexpr-preop.c:8:4: error: bad constant expression
+constexpr-preop.c:9:4: error: bad constant expression
+constexpr-preop.c:14:4: error: bad integer constant expression
+constexpr-preop.c:15:4: error: bad integer constant expression
+ * check-error-end
+ */