@@ -3056,23 +3056,27 @@ static struct symbol *evaluate_offsetof(struct expression *expr)
} else {
struct expression *idx = expr->index, *m;
struct symbol *i_type = evaluate_expression(idx);
+ unsigned old_idx_flags;
int i_class = classify_type(i_type, &i_type);
+
if (!is_int(i_class)) {
expression_error(expr, "non-integer index");
return NULL;
}
unrestrict(idx, i_class, &i_type);
+ old_idx_flags = idx->flags;
idx = cast_to(idx, size_t_ctype);
+ idx->flags = old_idx_flags;
m = alloc_const_expression(expr->pos,
bits_to_bytes(ctype->bit_size));
m->ctype = size_t_ctype;
- m->flags |= CEF_SET_ICE;
+ m->flags = CEF_SET_INT;
expr->type = EXPR_BINOP;
expr->left = idx;
expr->right = m;
expr->op = '*';
expr->ctype = size_t_ctype;
- expr->flags = m->flags & idx->flags;
+ expr->flags = m->flags & idx->flags & ~CEF_CONST_MASK;
}
}
if (e) {
@@ -199,7 +199,6 @@ static struct token *builtin_offsetof_expr(struct token *token,
return expect(token, ')', "at end of __builtin_offset");
case SPECIAL_DEREFERENCE:
e = alloc_expression(token->pos, EXPR_OFFSETOF);
- e->flags = CEF_SET_ICE;
e->op = '[';
*p = e;
p = &e->down;
@@ -207,7 +206,6 @@ static struct token *builtin_offsetof_expr(struct token *token,
case '.':
token = token->next;
e = alloc_expression(token->pos, EXPR_OFFSETOF);
- e->flags = CEF_SET_ICE;
e->op = '.';
if (token_type(token) != TOKEN_IDENT) {
sparse_error(token->pos, "Expected member name");
@@ -219,7 +217,6 @@ static struct token *builtin_offsetof_expr(struct token *token,
case '[':
token = token->next;
e = alloc_expression(token->pos, EXPR_OFFSETOF);
- e->flags = CEF_SET_ICE;
e->op = '[';
token = parse_expression(token, &e->index);
token = expect(token, ']',
new file mode 100644
@@ -0,0 +1,21 @@
+struct A {
+ int a[1];
+ int b;
+};
+
+extern int c;
+
+static int o[] = {
+ [__builtin_offsetof(struct A, b)] = 0, // OK
+ [__builtin_offsetof(struct A, a[0])] = 0, // OK
+ [__builtin_offsetof(struct A, a[0*0])] = 0, // OK
+ [__builtin_offsetof(struct A, a[c])] = 0 // KO
+};
+
+/*
+ * check-name: __builtin_offsetof() constness verification.
+ *
+ * check-error-start
+constexpr-offsetof.c:12:39: error: bad constant expression
+ * check-error-end
+ */