aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorJosh Triplett <josh@freedesktop.org>2007-06-26 15:43:08 -0700
committerJosh Triplett <josh@freedesktop.org>2007-06-26 15:43:08 -0700
commit36e13ae4117a23f725f05b6a03ea7ae12c6edc39 (patch)
tree64d295da21135e07b541bcc5703cbf05dab91118
parent185d8836c3d6139f285152f533cefce8a8289442 (diff)
parenta24a3adf3f0e3c22b0d98837090c55307f6fec84 (diff)
downloadsparse-dev-36e13ae4117a23f725f05b6a03ea7ae12c6edc39.tar.gz
Merge commit 'viro/integer-constant'
* commit 'viro/integer-constant': [PATCH] fix handling of integer constant expressions [PATCH] implement __builtin_offsetof()
-rw-r--r--evaluate.c127
-rw-r--r--expand.c17
-rw-r--r--expression.c135
-rw-r--r--expression.h19
-rw-r--r--ident-list.h1
-rw-r--r--inline.c18
-rw-r--r--lib.c1
-rw-r--r--parse.c10
-rw-r--r--show-parse.c1
9 files changed, 314 insertions, 15 deletions
diff --git a/evaluate.c b/evaluate.c
index 07ebf0c4..bcac1d2f 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -311,6 +311,7 @@ static struct expression * cast_to(struct expression *old, struct symbol *type)
}
expr = alloc_expression(old->pos, EXPR_IMPLIED_CAST);
+ expr->flags = old->flags;
expr->ctype = type;
expr->cast_type = type;
expr->cast_expression = old;
@@ -403,6 +404,7 @@ static struct symbol *bad_expr_type(struct expression *expr)
break;
}
+ expr->flags = 0;
return expr->ctype = &bad_ctype;
}
@@ -880,6 +882,10 @@ static struct symbol *evaluate_logical(struct expression *expr)
return NULL;
expr->ctype = &bool_ctype;
+ if (expr->flags) {
+ if (!(expr->left->flags & expr->right->flags & Int_const_expr))
+ expr->flags = 0;
+ }
return &bool_ctype;
}
@@ -890,6 +896,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 & Int_const_expr))
+ expr->flags = 0;
+ }
+
/* number op number */
if (lclass & rclass & TYPE_NUM) {
if ((lclass | rclass) & TYPE_FLOAT) {
@@ -968,6 +979,11 @@ static struct symbol *evaluate_compare(struct expression *expr)
struct symbol *ctype;
int lclass, rclass;
+ if (expr->flags) {
+ if (!(expr->left->flags & expr->right->flags & Int_const_expr))
+ expr->flags = 0;
+ }
+
/* Type types? */
if (is_type_type(ltype) && is_type_type(rtype))
goto OK;
@@ -1057,6 +1073,13 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr)
true = &expr->cond_true;
}
+ if (expr->flags) {
+ int flags = expr->conditional->flags & Int_const_expr;
+ flags &= (*true)->flags & expr->cond_false->flags;
+ if (!flags)
+ expr->flags = 0;
+ }
+
lclass = classify_type(ltype, &ltype);
rclass = classify_type(rtype, &rtype);
if (lclass & rclass & TYPE_NUM) {
@@ -1436,6 +1459,7 @@ static struct symbol *evaluate_addressof(struct expression *expr)
}
ctype = op->ctype;
*expr = *op->unop;
+ expr->flags = 0;
if (expr->type == EXPR_SYMBOL) {
struct symbol *sym = expr->symbol;
@@ -1463,6 +1487,7 @@ static struct symbol *evaluate_dereference(struct expression *expr)
/* Simplify: *&(expr) => (expr) */
if (op->type == EXPR_PREOP && op->op == '&') {
*expr = *op->unop;
+ expr->flags = 0;
return expr->ctype;
}
@@ -1540,6 +1565,8 @@ static struct symbol *evaluate_postop(struct expression *expr)
static struct symbol *evaluate_sign(struct expression *expr)
{
struct symbol *ctype = expr->unop->ctype;
+ if (expr->flags && !(expr->unop->flags & Int_const_expr))
+ expr->flags = 0;
if (is_int_type(ctype)) {
struct symbol *rtype = rtype = integer_promotion(ctype);
expr->unop = cast_to(expr->unop, rtype);
@@ -1588,6 +1615,8 @@ static struct symbol *evaluate_preop(struct expression *expr)
return evaluate_postop(expr);
case '!':
+ if (expr->flags && !(expr->unop->flags & Int_const_expr))
+ expr->flags = 0;
if (is_safe_type(ctype))
warning(expr->pos, "testing a 'safe expression'");
if (is_float_type(ctype)) {
@@ -2477,6 +2506,15 @@ static struct symbol *evaluate_cast(struct expression *expr)
degenerate(target);
class1 = classify_type(ctype, &t1);
+
+ /* cast to non-integer type -> not an integer constant expression */
+ if (!is_int(class1))
+ expr->flags = 0;
+ /* if argument turns out to be not an integer constant expression *and*
+ it was not a floating literal to start with -> too bad */
+ else if (expr->flags == Int_const_expr &&
+ !(target->flags & Int_const_expr))
+ expr->flags = 0;
/*
* You can always throw a value away by casting to
* "void" - that's an implicit "force". Note that
@@ -2608,6 +2646,92 @@ static struct symbol *evaluate_call(struct expression *expr)
return expr->ctype;
}
+static struct symbol *evaluate_offsetof(struct expression *expr)
+{
+ struct expression *e = expr->down;
+ struct symbol *ctype = expr->in;
+ int class;
+
+ if (expr->op == '.') {
+ struct symbol *field;
+ int offset = 0;
+ if (!ctype) {
+ expression_error(expr, "expected structure or union");
+ return NULL;
+ }
+ examine_symbol_type(ctype);
+ class = classify_type(ctype, &ctype);
+ if (class != TYPE_COMPOUND) {
+ expression_error(expr, "expected structure or union");
+ return NULL;
+ }
+
+ field = find_identifier(expr->ident, ctype->symbol_list, &offset);
+ if (!field) {
+ expression_error(expr, "unknown member");
+ return NULL;
+ }
+ ctype = field;
+ expr->type = EXPR_VALUE;
+ expr->flags = Int_const_expr;
+ expr->value = offset;
+ expr->ctype = size_t_ctype;
+ } else {
+ if (!ctype) {
+ expression_error(expr, "expected structure or union");
+ return NULL;
+ }
+ examine_symbol_type(ctype);
+ class = classify_type(ctype, &ctype);
+ if (class != (TYPE_COMPOUND | TYPE_PTR)) {
+ expression_error(expr, "expected array");
+ return NULL;
+ }
+ ctype = ctype->ctype.base_type;
+ if (!expr->index) {
+ expr->type = EXPR_VALUE;
+ expr->flags = Int_const_expr;
+ expr->value = 0;
+ expr->ctype = size_t_ctype;
+ } else {
+ struct expression *idx = expr->index, *m;
+ struct symbol *i_type = evaluate_expression(idx);
+ 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);
+ idx = cast_to(idx, size_t_ctype);
+ m = alloc_const_expression(expr->pos,
+ ctype->bit_size >> 3);
+ m->ctype = size_t_ctype;
+ m->flags = Int_const_expr;
+ expr->type = EXPR_BINOP;
+ expr->left = idx;
+ expr->right = m;
+ expr->op = '*';
+ expr->ctype = size_t_ctype;
+ expr->flags = m->flags & idx->flags & Int_const_expr;
+ }
+ }
+ if (e) {
+ struct expression *copy = __alloc_expression(0);
+ *copy = *expr;
+ if (e->type == EXPR_OFFSETOF)
+ e->in = ctype;
+ if (!evaluate_expression(e))
+ return NULL;
+ expr->type = EXPR_BINOP;
+ expr->flags = e->flags & copy->flags & Int_const_expr;
+ expr->op = '+';
+ expr->ctype = size_t_ctype;
+ expr->left = copy;
+ expr->right = e;
+ }
+ return size_t_ctype;
+}
+
struct symbol *evaluate_expression(struct expression *expr)
{
if (!expr)
@@ -2688,6 +2812,9 @@ struct symbol *evaluate_expression(struct expression *expr)
expr->ctype = &type_ctype;
return &type_ctype;
+ case EXPR_OFFSETOF:
+ return evaluate_offsetof(expr);
+
/* These can not exist as stand-alone expressions */
case EXPR_INITIALIZER:
case EXPR_IDENTIFIER:
diff --git a/expand.c b/expand.c
index a46f1c24..f9455181 100644
--- a/expand.c
+++ b/expand.c
@@ -968,6 +968,7 @@ static int expand_expression(struct expression *expr)
case EXPR_SIZEOF:
case EXPR_PTRSIZEOF:
case EXPR_ALIGNOF:
+ case EXPR_OFFSETOF:
expression_error(expr, "internal front-end error: sizeof in expansion?");
return UNSAFE;
}
@@ -1143,7 +1144,7 @@ static int expand_statement(struct statement *stmt)
return SIDE_EFFECTS;
}
-long long get_expression_value(struct expression *expr)
+static long long __get_expression_value(struct expression *expr, int strict)
{
long long value, mask;
struct symbol *ctype;
@@ -1160,6 +1161,10 @@ long long get_expression_value(struct expression *expr)
expression_error(expr, "bad constant expression");
return 0;
}
+ if (strict && !(expr->flags & Int_const_expr)) {
+ expression_error(expr, "bad integer constant expression");
+ return 0;
+ }
value = expr->value;
mask = 1ULL << (ctype->bit_size-1);
@@ -1172,3 +1177,13 @@ long long get_expression_value(struct expression *expr)
}
return value;
}
+
+long long get_expression_value(struct expression *expr)
+{
+ return __get_expression_value(expr, 0);
+}
+
+long long const_expression_value(struct expression *expr)
+{
+ return __get_expression_value(expr, 1);
+}
diff --git a/expression.c b/expression.c
index a40ab2bc..d36c3d2f 100644
--- a/expression.c
+++ b/expression.c
@@ -117,6 +117,7 @@ static struct token *parse_type(struct token *token, struct expression **tree)
{
struct symbol *sym;
*tree = alloc_expression(token->pos, EXPR_TYPE);
+ (*tree)->flags = Int_const_expr; /* sic */
token = typename(token, &sym);
if (sym->ident)
sparse_error(token->pos,
@@ -131,6 +132,7 @@ static struct token *builtin_types_compatible_p_expr(struct token *token,
{
struct expression *expr = alloc_expression(
token->pos, EXPR_COMPARE);
+ expr->flags = Int_const_expr;
expr->op = SPECIAL_EQUAL;
token = token->next;
if (!match_op(token, '('))
@@ -152,6 +154,72 @@ static struct token *builtin_types_compatible_p_expr(struct token *token,
return token;
}
+static struct token *builtin_offsetof_expr(struct token *token,
+ struct expression **tree)
+{
+ struct expression *expr = NULL;
+ struct expression **p = &expr;
+ struct symbol *sym;
+ int op = '.';
+
+ token = token->next;
+ if (!match_op(token, '('))
+ return expect(token, '(', "after __builtin_offset");
+
+ token = token->next;
+ token = typename(token, &sym);
+ if (sym->ident)
+ sparse_error(token->pos,
+ "type expression should not include identifier "
+ "\"%s\"", sym->ident->name);
+
+ if (!match_op(token, ','))
+ return expect(token, ',', "in __builtin_offset");
+
+ while (1) {
+ struct expression *e;
+ switch (op) {
+ case ')':
+ expr->in = sym;
+ *tree = expr;
+ default:
+ return expect(token, ')', "at end of __builtin_offset");
+ case SPECIAL_DEREFERENCE:
+ e = alloc_expression(token->pos, EXPR_OFFSETOF);
+ e->flags = Int_const_expr;
+ e->op = '[';
+ *p = e;
+ p = &e->down;
+ /* fall through */
+ case '.':
+ token = token->next;
+ e = alloc_expression(token->pos, EXPR_OFFSETOF);
+ e->flags = Int_const_expr;
+ e->op = '.';
+ if (token_type(token) != TOKEN_IDENT) {
+ sparse_error(token->pos, "Expected member name");
+ return token;
+ }
+ e->ident = token->ident;
+ token = token->next;
+ break;
+ case '[':
+ token = token->next;
+ e = alloc_expression(token->pos, EXPR_OFFSETOF);
+ e->flags = Int_const_expr;
+ e->op = '[';
+ token = parse_expression(token, &e->index);
+ token = expect(token, ']',
+ "at end of array dereference");
+ if (!e->index)
+ return token;
+ }
+ *p = e;
+ p = &e->down;
+ op = token_type(token) == TOKEN_SPECIAL ? token->special : 0;
+ }
+}
+
static struct token *string_expression(struct token *token, struct expression *expr)
{
struct string *string = token->string;
@@ -290,6 +358,7 @@ got_it:
"likely to produce unsigned long (and a warning) here",
show_token(token));
expr->type = EXPR_VALUE;
+ expr->flags = Int_const_expr;
expr->ctype = ctype_integer(modifiers);
expr->value = value;
return;
@@ -314,6 +383,7 @@ Float:
else
goto Enoint;
+ expr->flags = Float_literal;
expr->type = EXPR_FVALUE;
return;
@@ -328,6 +398,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
switch (token_type(token)) {
case TOKEN_CHAR:
expr = alloc_expression(token->pos, EXPR_VALUE);
+ expr->flags = Int_const_expr;
expr->ctype = &int_ctype;
expr->value = (unsigned char) token->character;
token = token->next;
@@ -335,12 +406,13 @@ struct token *primary_expression(struct token *token, struct expression **tree)
case TOKEN_NUMBER:
expr = alloc_expression(token->pos, EXPR_VALUE);
- get_number_value(expr, token);
+ get_number_value(expr, token); /* will see if it's an integer */
token = token->next;
break;
case TOKEN_ZERO_IDENT: {
expr = alloc_expression(token->pos, EXPR_SYMBOL);
+ expr->flags = Int_const_expr;
expr->ctype = &int_ctype;
expr->symbol = &zero_int;
expr->symbol_name = token->ident;
@@ -359,11 +431,16 @@ struct token *primary_expression(struct token *token, struct expression **tree)
token = builtin_types_compatible_p_expr(token, &expr);
break;
}
+ if (token->ident == &__builtin_offsetof_ident) {
+ token = builtin_offsetof_expr(token, &expr);
+ break;
+ }
} else if (sym->enum_member) {
expr = alloc_expression(token->pos, EXPR_VALUE);
*expr = *sym->initializer;
/* we want the right position reported, thus the copy */
expr->pos = token->pos;
+ expr->flags = Int_const_expr;
token = next;
break;
}
@@ -398,10 +475,13 @@ 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)) {
expr = alloc_expression(token->pos, EXPR_TYPE);
+ expr->flags = Int_const_expr; /* sic */
token = typename(token->next, &expr->symbol);
token = expect(token, ']', "in type expression");
break;
@@ -516,6 +596,7 @@ static struct token *type_info_expression(struct token *token,
struct expression *expr = alloc_expression(token->pos, type);
*tree = expr;
+ expr->flags = Int_const_expr; /* XXX: VLA support will need that changed */
token = token->next;
if (!match_op(token, '(') || !lookup_type(token->next))
return unary_expression(token, &expr->cast_expression);
@@ -565,7 +646,7 @@ static struct token *unary_expression(struct token *token, struct expression **t
if (token_type(token) == TOKEN_SPECIAL) {
if (match_oplist(token->special,
SPECIAL_INCREMENT, SPECIAL_DECREMENT,
- '&', '*', '+', '-', '~', '!', 0)) {
+ '&', '*', 0)) {
struct expression *unop;
struct expression *unary;
struct token *next;
@@ -581,7 +662,24 @@ static struct token *unary_expression(struct token *token, struct expression **t
*tree = unary;
return next;
}
+ /* possibly constant ones */
+ if (match_oplist(token->special, '+', '-', '~', '!', 0)) {
+ struct expression *unop;
+ struct expression *unary;
+ struct token *next;
+ next = cast_expression(token->next, &unop);
+ if (!unop) {
+ sparse_error(token->pos, "Syntax error in unary expression");
+ return next;
+ }
+ unary = alloc_expression(token->pos, EXPR_PREOP);
+ unary->op = token->special;
+ unary->unop = unop;
+ unary->flags = unop->flags & Int_const_expr;
+ *tree = unary;
+ return next;
+ }
/* Gcc extension: &&label gives the address of a label */
if (match_op(token, SPECIAL_LOGICAL_AND) &&
token_type(token->next) == TOKEN_IDENT) {
@@ -615,6 +713,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr
struct token *next = token->next;
if (lookup_type(next)) {
struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
+ struct expression *v;
struct symbol *sym;
token = typename(next, &sym);
@@ -625,7 +724,14 @@ static struct token *cast_expression(struct token *token, struct expression **tr
return postfix_expression(token, tree, cast);
}
*tree = cast;
- token = cast_expression(token, &cast->cast_expression);
+ token = cast_expression(token, &v);
+ if (!v)
+ return token;
+ cast->cast_expression = v;
+ if (v->flags & Int_const_expr)
+ cast->flags = Int_const_expr;
+ else if (v->flags & Float_literal) /* and _not_ int */
+ cast->flags = Int_const_expr | Float_literal;
return token;
}
}
@@ -645,9 +751,9 @@ static struct token *cast_expression(struct token *token, struct expression **tr
* than create a data structure for it.
*/
-#define LR_BINOP_EXPRESSION(token, tree, type, inner, compare) \
+#define __LR_BINOP_EXPRESSION(__token, tree, type, inner, compare, is_const) \
struct expression *left = NULL; \
- struct token * next = inner(token, &left); \
+ struct token * next = inner(__token, &left); \
\
if (left) { \
while (token_type(next) == TOKEN_SPECIAL) { \
@@ -662,6 +768,9 @@ 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; \
} \
+ if (is_const) \
+ top->flags = left->flags & right->flags \
+ & Int_const_expr; \
top->op = op; \
top->left = left; \
top->right = right; \
@@ -672,6 +781,12 @@ out: \
*tree = left; \
return next; \
+#define LR_BINOP_EXPRESSION(token, tree, type, inner, compare) \
+ __LR_BINOP_EXPRESSION((token), (tree), (type), (inner), (compare), 1)
+
+#define LR_BINOP_EXPRESSION_NONCONST(token, tree, type, inner, compare) \
+ __LR_BINOP_EXPRESSION((token), (tree), (type), (inner), (compare), 0)
+
static struct token *multiplicative_expression(struct token *token, struct expression **tree)
{
@@ -765,6 +880,14 @@ 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_true) {
+ int is_const = expr->left->flags &
+ expr->cond_false->flags &
+ Int_const_expr;
+ if (expr->cond_true)
+ is_const &= expr->cond_true->flags;
+ expr->flags = is_const;
+ }
}
return token;
}
@@ -795,7 +918,7 @@ struct token *assignment_expression(struct token *token, struct expression **tre
static struct token *comma_expression(struct token *token, struct expression **tree)
{
- LR_BINOP_EXPRESSION(
+ LR_BINOP_EXPRESSION_NONCONST(
token, tree, EXPR_COMMA, assignment_expression,
(op == ',')
);
diff --git a/expression.h b/expression.h
index 1bf02c4a..a9131532 100644
--- a/expression.h
+++ b/expression.h
@@ -44,10 +44,17 @@ enum expression_type {
EXPR_POS, // position in initializer
EXPR_FVALUE,
EXPR_SLICE,
+ EXPR_OFFSETOF,
};
+enum {
+ Int_const_expr = 1,
+ Float_literal = 2,
+}; /* for expr->flags */
+
struct expression {
- enum expression_type type;
+ enum expression_type type:8;
+ unsigned flags:8;
int op;
struct position pos;
struct symbol *ctype;
@@ -127,11 +134,21 @@ struct expression {
unsigned int init_offset, init_nr;
struct expression *init_expr;
};
+ // EXPR_OFFSETOF
+ struct {
+ struct symbol *in;
+ struct expression *down;
+ union {
+ struct ident *ident;
+ struct expression *index;
+ };
+ };
};
};
/* Constant expression values */
long long get_expression_value(struct expression *);
+long long const_expression_value(struct expression *);
/* Expression parsing */
struct token *parse_expression(struct token *token, struct expression **tree);
diff --git a/ident-list.h b/ident-list.h
index 0f654bff..b183eac0 100644
--- a/ident-list.h
+++ b/ident-list.h
@@ -29,6 +29,7 @@ IDENT(asm); IDENT_RESERVED(__asm); IDENT_RESERVED(__asm__);
IDENT(alignof); IDENT_RESERVED(__alignof); IDENT_RESERVED(__alignof__);
IDENT_RESERVED(__sizeof_ptr__);
IDENT_RESERVED(__builtin_types_compatible_p);
+IDENT_RESERVED(__builtin_offsetof);
/* Attribute names */
IDENT(packed); IDENT(__packed__);
diff --git a/inline.c b/inline.c
index f80403c0..061261a2 100644
--- a/inline.c
+++ b/inline.c
@@ -237,7 +237,23 @@ static struct expression * copy_expression(struct expression *expr)
expr->init_expr = val;
break;
}
-
+ case EXPR_OFFSETOF: {
+ struct expression *val = copy_expression(expr->down);
+ if (expr->op == '.') {
+ if (expr->down != val) {
+ expr = dup_expression(expr);
+ expr->down = val;
+ }
+ } else {
+ struct expression *idx = copy_expression(expr->index);
+ if (expr->down != val || expr->index != idx) {
+ expr = dup_expression(expr);
+ expr->down = val;
+ expr->index = idx;
+ }
+ }
+ break;
+ }
default:
warning(expr->pos, "trying to copy expression type %d", expr->type);
}
diff --git a/lib.c b/lib.c
index 7f6334c9..7fea4742 100644
--- a/lib.c
+++ b/lib.c
@@ -609,7 +609,6 @@ void create_builtin_stream(void)
add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n");
add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n");
add_pre_buffer("#define __builtin_va_end(arg)\n");
- add_pre_buffer("#define __builtin_offsetof(type, name) ((__SIZE_TYPE__)&((type *)(0ul))->name)\n");
/* FIXME! We need to do these as special magic macros at expansion time! */
add_pre_buffer("#define __BASE_FILE__ \"base_file.c\"\n");
diff --git a/parse.c b/parse.c
index 4e8a18b9..cb9f87a3 100644
--- a/parse.c
+++ b/parse.c
@@ -802,7 +802,7 @@ static struct token *attribute_aligned(struct token *token, struct symbol *attr,
if (match_op(token, '(')) {
token = parens_expression(token, &expr, "in attribute");
if (expr)
- alignment = get_expression_value(expr);
+ alignment = const_expression_value(expr);
}
ctype->alignment = alignment;
return token;
@@ -820,7 +820,7 @@ static struct token *attribute_address_space(struct token *token, struct symbol
token = expect(token, '(', "after address_space attribute");
token = conditional_expression(token, &expr);
if (expr)
- ctype->as = get_expression_value(expr);
+ ctype->as = const_expression_value(expr);
token = expect(token, ')', "after address_space attribute");
return token;
}
@@ -1258,7 +1258,7 @@ static struct token *handle_bitfield(struct token *token, struct symbol *decl)
bitfield = alloc_indirect_symbol(token->pos, ctype, SYM_BITFIELD);
token = conditional_expression(token->next, &expr);
- width = get_expression_value(expr);
+ width = const_expression_value(expr);
bitfield->bit_size = width;
if (width < 0 || width > INT_MAX) {
@@ -1844,10 +1844,10 @@ static struct expression *index_expression(struct expression *from, struct expre
int idx_from, idx_to;
struct expression *expr = alloc_expression(from->pos, EXPR_INDEX);
- idx_from = get_expression_value(from);
+ idx_from = const_expression_value(from);
idx_to = idx_from;
if (to) {
- idx_to = get_expression_value(to);
+ idx_to = const_expression_value(to);
if (idx_to < idx_from || idx_from < 0)
warning(from->pos, "nonsense array initializer index range");
}
diff --git a/show-parse.c b/show-parse.c
index 0bef01cb..07ee7635 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -1049,6 +1049,7 @@ int show_expression(struct expression *expr)
case EXPR_SIZEOF:
case EXPR_PTRSIZEOF:
case EXPR_ALIGNOF:
+ case EXPR_OFFSETOF:
warning(expr->pos, "invalid expression after evaluation");
return 0;
case EXPR_CAST: