Fix up the 'value is so large it is XXXX' message in the presense
[smatch.git] / evaluate.c
blob8813c00f2108ca370d53f95e75183dd79758790b
1 /*
2 * sparse/evaluate.c
4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
6 * Evaluate constant expressions.
7 */
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <limits.h>
17 #include "lib.h"
18 #include "parse.h"
19 #include "token.h"
20 #include "symbol.h"
21 #include "target.h"
22 #include "expression.h"
24 static int evaluate_symbol(struct expression *expr)
26 struct symbol *sym = expr->symbol;
27 struct symbol *base_type;
29 if (!sym) {
30 warn(expr->token, "undefined identifier '%s'", show_token(expr->token));
31 return 0;
33 examine_symbol_type(sym);
34 base_type = sym->ctype.base_type;
35 if (!base_type)
36 return 0;
38 expr->ctype = base_type;
39 examine_symbol_type(base_type);
41 /* enum's can be turned into plain values */
42 if (base_type->type == SYM_ENUM) {
43 expr->type = EXPR_VALUE;
44 expr->value = sym->value;
46 return 1;
49 static int get_int_value(struct expression *expr, const char *str)
51 unsigned long long value = 0;
52 unsigned int base = 10, digit, bits;
53 unsigned long modifiers, extramod;
55 switch (str[0]) {
56 case 'x':
57 base = 18; // the -= 2 for the octal case will
58 str++; // skip the 'x'
59 /* fallthrough */
60 case 'o':
61 str++; // skip the 'o' or 'x/X'
62 base -= 2; // the fall-through will make this 8
64 while ((digit = hexval(*str)) < base) {
65 value = value * base + digit;
66 str++;
68 modifiers = 0;
69 for (;;) {
70 char c = *str++;
71 if (c == 'u' || c == 'U') {
72 modifiers |= MOD_UNSIGNED;
73 continue;
75 if (c == 'l' || c == 'L') {
76 if (modifiers & MOD_LONG)
77 modifiers |= MOD_LONGLONG;
78 modifiers |= MOD_LONG;
79 continue;
81 break;
84 bits = BITS_IN_LONGLONG;
85 extramod = 0;
86 if (!(modifiers & MOD_LONGLONG)) {
87 if (value & (~0ULL << BITS_IN_LONG)) {
88 extramod = MOD_LONGLONG | MOD_LONG;
89 } else {
90 bits = BITS_IN_LONG;
91 if (!(modifiers & MOD_LONG)) {
92 if (value & (~0ULL << BITS_IN_INT)) {
93 extramod = MOD_LONG;
94 } else
95 bits = BITS_IN_INT;
99 if (!(modifiers & MOD_UNSIGNED)) {
100 if (value & (1ULL << (bits-1))) {
101 extramod |= MOD_UNSIGNED;
104 if (extramod) {
106 * Special case: "int" gets promoted directly to "long"
107 * for normal decimal numbers..
109 modifiers |= extramod;
110 if (base == 10 && modifiers == MOD_UNSIGNED) {
111 modifiers = MOD_LONG;
112 if (BITS_IN_LONG == BITS_IN_INT)
113 modifiers = MOD_LONG | MOD_UNSIGNED;
115 warn(expr->token, "value is so big it is%s%s%s",
116 (modifiers & MOD_UNSIGNED) ? " unsigned":"",
117 (modifiers & MOD_LONG) ? " long":"",
118 (modifiers & MOD_LONGLONG) ? " long":"");
121 expr->type = EXPR_VALUE;
122 expr->ctype = ctype_integer(modifiers);
123 expr->value = value;
124 return 1;
127 static int evaluate_constant(struct expression *expr)
129 struct token *token = expr->token;
131 switch (token->type) {
132 case TOKEN_INTEGER:
133 return get_int_value(expr, token->integer);
135 case TOKEN_CHAR:
136 expr->type = EXPR_VALUE;
137 expr->ctype = &int_ctype;
138 expr->value = (char) token->character;
139 return 1;
140 case TOKEN_STRING:
141 expr->ctype = &string_ctype;
142 return 1;
143 default:
144 warn(token, "non-typed expression");
146 return 0;
149 static struct symbol *bigger_int_type(struct symbol *left, struct symbol *right)
151 unsigned long lmod, rmod, mod;
153 if (left == right)
154 return left;
156 if (left->bit_size > right->bit_size)
157 return left;
159 if (right->bit_size > left->bit_size)
160 return right;
162 /* Same size integers - promote to unsigned, promote to long */
163 lmod = left->ctype.modifiers;
164 rmod = right->ctype.modifiers;
165 mod = lmod | rmod;
166 if (mod == lmod)
167 return left;
168 if (mod == rmod)
169 return right;
170 return ctype_integer(mod);
173 static int cast_value(struct expression *expr, struct symbol *newtype,
174 struct expression *old, struct symbol *oldtype)
176 int old_size = oldtype->bit_size;
177 int new_size = newtype->bit_size;
178 long long value, mask, ormask, andmask;
179 int is_signed;
181 // FIXME! We don't handle FP casts of constant values yet
182 if (newtype->ctype.base_type == &fp_type)
183 return 0;
184 if (oldtype->ctype.base_type == &fp_type)
185 return 0;
187 // For pointers and integers, we can just move the value around
188 expr->type = EXPR_VALUE;
189 if (old_size == new_size) {
190 expr->value = old->value;
191 return 1;
194 // expand it to the full "long long" value
195 is_signed = !(oldtype->ctype.modifiers & MOD_UNSIGNED);
196 mask = 1ULL << (old_size-1);
197 value = old->value;
198 if (!(value & mask))
199 is_signed = 0;
200 andmask = mask | (mask-1);
201 ormask = ~andmask;
202 if (!is_signed)
203 ormask = 0;
204 value = (value & andmask) | ormask;
206 // Truncate it to the new size
207 mask = 1ULL << (new_size-1);
208 mask = mask | (mask-1);
209 expr->value = value & mask;
210 return 1;
213 static struct expression * cast_to(struct expression *old, struct symbol *type)
215 struct expression *expr = alloc_expression(old->token, EXPR_CAST);
216 expr->ctype = type;
217 expr->cast_type = type;
218 expr->cast_expression = old;
219 if (old->type == EXPR_VALUE)
220 cast_value(expr, type, old, old->ctype);
221 return expr;
224 static int is_ptr_type(struct symbol *type)
226 return type->type == SYM_PTR || type->type == SYM_ARRAY || type->type == SYM_FN;
229 static int is_int_type(struct symbol *type)
231 return type->ctype.base_type == &int_type;
234 static int bad_expr_type(struct expression *expr)
236 warn(expr->token, "incompatible types for operation");
237 return 0;
240 static struct symbol * compatible_integer_binop(struct expression *expr)
242 struct expression *left = expr->left, *right = expr->right;
243 struct symbol *ltype = left->ctype, *rtype = right->ctype;
245 /* Integer promotion? */
246 if (ltype->type == SYM_ENUM)
247 ltype = &int_ctype;
248 if (rtype->type == SYM_ENUM)
249 rtype = &int_ctype;
250 if (is_int_type(ltype) && is_int_type(rtype)) {
251 struct symbol *ctype = bigger_int_type(ltype, rtype);
253 /* Don't bother promoting same-size entities, it only adds clutter */
254 if (ltype->bit_size != ctype->bit_size)
255 expr->left = cast_to(left, ctype);
256 if (rtype->bit_size != ctype->bit_size)
257 expr->right = cast_to(right, ctype);
258 return ctype;
260 return NULL;
263 static int evaluate_int_binop(struct expression *expr)
265 struct symbol *ctype = compatible_integer_binop(expr);
266 if (ctype) {
267 expr->ctype = ctype;
268 return 1;
270 return bad_expr_type(expr);
273 static int evaluate_ptr_add(struct expression *expr, struct expression *ptr, struct expression *i)
275 struct symbol *ctype;
276 struct symbol *ptr_type = ptr->ctype;
277 struct symbol *i_type = i->ctype;
279 if (i_type->type == SYM_ENUM)
280 i_type = &int_ctype;
281 if (!is_int_type(i_type))
282 return bad_expr_type(expr);
284 ctype = ptr_type->ctype.base_type;
285 examine_symbol_type(ctype);
287 expr->ctype = ptr_type;
288 if (ctype->bit_size > BITS_IN_CHAR) {
289 struct expression *add = expr;
290 struct expression *mul = alloc_expression(expr->token, EXPR_BINOP);
291 struct expression *val = alloc_expression(expr->token, EXPR_VALUE);
293 val->ctype = size_t_ctype;
294 val->value = ctype->bit_size >> 3;
296 mul->op = '*';
297 mul->ctype = size_t_ctype;
298 mul->left = i;
299 mul->right = val;
301 /* Leave 'add->op' as 'expr->op' - either '+' or '-' */
302 add->ctype = ptr_type;
303 add->left = ptr;
304 add->right = mul;
307 return 1;
310 static int evaluate_plus(struct expression *expr)
312 struct expression *left = expr->left, *right = expr->right;
313 struct symbol *ltype = left->ctype, *rtype = right->ctype;
315 if (is_ptr_type(ltype))
316 return evaluate_ptr_add(expr, left, right);
318 if (is_ptr_type(rtype))
319 return evaluate_ptr_add(expr, right, left);
321 // FIXME! FP promotion
322 return evaluate_int_binop(expr);
325 static struct symbol *same_ptr_types(struct symbol *a, struct symbol *b)
327 a = a->ctype.base_type;
328 b = b->ctype.base_type;
330 if (a->bit_size != b->bit_size)
331 return NULL;
333 // FIXME! We should really check a bit more..
334 return a;
337 static int evaluate_ptr_sub(struct expression *expr, struct expression *l, struct expression *r)
339 struct symbol *ctype;
340 struct symbol *ltype = l->ctype, *rtype = r->ctype;
343 * If it is an integer subtract: the ptr add case will do the
344 * right thing.
346 if (!is_ptr_type(rtype))
347 return evaluate_ptr_add(expr, l, r);
350 ctype = same_ptr_types(ltype, rtype);
351 if (!ctype) {
352 warn(expr->token, "subtraction of different types can't work");
353 return 0;
355 examine_symbol_type(ctype);
357 expr->ctype = ssize_t_ctype;
358 if (ctype->bit_size > BITS_IN_CHAR) {
359 struct expression *sub = alloc_expression(expr->token, EXPR_BINOP);
360 struct expression *div = expr;
361 struct expression *val = alloc_expression(expr->token, EXPR_VALUE);
363 val->ctype = size_t_ctype;
364 val->value = ctype->bit_size >> 3;
366 sub->op = '-';
367 sub->ctype = ssize_t_ctype;
368 sub->left = l;
369 sub->right = r;
371 div->op = '/';
372 div->left = sub;
373 div->right = val;
376 return 1;
379 static int evaluate_minus(struct expression *expr)
381 struct expression *left = expr->left, *right = expr->right;
382 struct symbol *ltype = left->ctype;
384 if (is_ptr_type(ltype))
385 return evaluate_ptr_sub(expr, left, right);
387 // FIXME! FP promotion
388 return evaluate_int_binop(expr);
391 static int evaluate_logical(struct expression *expr)
393 // FIXME! Short-circuit, FP and pointers!
394 expr->ctype = &bool_ctype;
395 return 1;
398 static int evaluate_arithmetic(struct expression *expr)
400 // FIXME! Floating-point promotion!
401 return evaluate_int_binop(expr);
404 static int evaluate_binop(struct expression *expr)
406 switch (expr->op) {
407 // addition can take ptr+int, fp and int
408 case '+':
409 return evaluate_plus(expr);
411 // subtraction can take ptr-ptr, fp and int
412 case '-':
413 return evaluate_minus(expr);
415 // Logical ops can take a lot of special stuff and have early-out
416 case SPECIAL_LOGICAL_AND:
417 case SPECIAL_LOGICAL_OR:
418 return evaluate_logical(expr);
420 // Arithmetic operations can take fp and int
421 case '*': case '/': case '%':
422 return evaluate_arithmetic(expr);
424 // The rest are integer operations (bitops)
425 // SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT
426 // '&', '^', '|'
427 default:
428 return evaluate_int_binop(expr);
432 static int evaluate_comma(struct expression *expr)
434 expr->ctype = expr->right->ctype;
435 return 1;
438 static int evaluate_compare(struct expression *expr)
440 struct expression *left = expr->left, *right = expr->right;
441 struct symbol *ltype = left->ctype, *rtype = right->ctype;
443 /* Pointer types? */
444 if (is_ptr_type(ltype) || is_ptr_type(rtype)) {
445 expr->ctype = &bool_ctype;
446 // FIXME! Check the types for compatibility
447 return 1;
450 if (compatible_integer_binop(expr)) {
451 expr->ctype = &bool_ctype;
452 return 1;
455 return bad_expr_type(expr);
458 static int evaluate_assignment(struct expression *expr)
460 struct expression *left = expr->left, *right = expr->right;
461 struct symbol *ltype = left->ctype, *rtype = right->ctype;
463 // FIXME! We need to cast and check the rigth side!
464 if (ltype->bit_size != rtype->bit_size)
465 expr->right = cast_to(right, ltype);
466 expr->ctype = expr->left->ctype;
467 return 1;
470 static int evaluate_preop(struct expression *expr)
472 struct symbol *ctype = expr->unop->ctype;
474 switch (expr->op) {
475 case '(':
476 expr->ctype = ctype;
477 return 1;
479 case '*':
480 if (ctype->type != SYM_PTR && ctype->type != SYM_ARRAY) {
481 warn(expr->token, "cannot derefence this type");
482 return 0;
484 examine_symbol_type(expr->ctype);
485 expr->ctype = ctype->ctype.base_type;
486 if (!expr->ctype) {
487 warn(expr->token, "undefined type");
488 return 0;
490 return 1;
492 case '&': {
493 struct symbol *symbol = alloc_symbol(expr->token, SYM_PTR);
494 symbol->ctype.base_type = ctype;
495 symbol->bit_size = BITS_IN_POINTER;
496 symbol->alignment = POINTER_ALIGNMENT;
497 expr->ctype = symbol;
498 return 1;
501 case '!':
502 expr->ctype = &bool_ctype;
503 return 1;
505 default:
506 expr->ctype = ctype;
507 return 1;
511 static int evaluate_postop(struct expression *expr)
513 struct symbol *ctype = expr->unop->ctype;
514 expr->ctype = ctype;
515 return 0;
518 struct symbol *find_identifier(struct ident *ident, struct symbol_list *_list, int *offset)
520 struct ptr_list *head = (struct ptr_list *)_list;
521 struct ptr_list *list = head;
523 if (!head)
524 return NULL;
525 do {
526 int i;
527 for (i = 0; i < list->nr; i++) {
528 struct symbol *sym = (struct symbol *) list->list[i];
529 if (sym->ident) {
530 if (sym->ident->ident != ident)
531 continue;
532 *offset = sym->offset;
533 return sym;
534 } else {
535 struct symbol *ctype = sym->ctype.base_type;
536 struct symbol *sub;
537 if (!ctype)
538 continue;
539 if (ctype->type != SYM_UNION && ctype->type != SYM_STRUCT)
540 continue;
541 sub = find_identifier(ident, ctype->symbol_list, offset);
542 if (!sub)
543 continue;
544 *offset += sym->offset;
545 return sub;
548 } while ((list = list->next) != head);
549 return NULL;
552 /* structure/union dereference */
553 static int evaluate_dereference(struct expression *expr)
555 int offset;
556 struct symbol *ctype, *member;
557 struct expression *deref = expr->deref, *add;
558 struct token *token = expr->member;
560 if (!evaluate_expression(deref) || !token)
561 return 0;
563 ctype = deref->ctype;
564 if (expr->op == SPECIAL_DEREFERENCE) {
565 if (ctype->type != SYM_PTR) {
566 warn(expr->token, "expected a pointer to a struct/union");
567 return 0;
569 ctype = ctype->ctype.base_type;
571 if (!ctype || (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION)) {
572 warn(expr->token, "expected structure or union");
573 return 0;
575 offset = 0;
576 member = find_identifier(token->ident, ctype->symbol_list, &offset);
577 if (!member) {
578 warn(expr->token, "no such struct/union member");
579 return 0;
582 add = deref;
583 if (offset != 0) {
584 add = alloc_expression(expr->token, EXPR_BINOP);
585 add->op = '+';
586 add->ctype = &ptr_ctype;
587 add->left = deref;
588 add->right = alloc_expression(expr->token, EXPR_VALUE);
589 add->right->ctype = &int_ctype;
590 add->right->value = offset;
593 ctype = member->ctype.base_type;
594 if (ctype->type == SYM_BITFIELD) {
595 expr->type = EXPR_BITFIELD;
596 expr->ctype = ctype->ctype.base_type;
597 expr->bitpos = member->bit_offset;
598 expr->nrbits = member->fieldwidth;
599 expr->address = add;
600 } else {
601 expr->type = EXPR_PREOP;
602 expr->op = '*';
603 expr->ctype = ctype;
604 expr->unop = add;
607 return 1;
610 static int evaluate_sizeof(struct expression *expr)
612 int size;
614 if (expr->cast_type) {
615 examine_symbol_type(expr->cast_type);
616 size = expr->cast_type->bit_size;
617 } else {
618 if (!evaluate_expression(expr->cast_expression))
619 return 0;
620 size = expr->cast_expression->ctype->bit_size;
622 if (size & 7) {
623 warn(expr->token, "cannot size expression");
624 return 0;
626 expr->type = EXPR_VALUE;
627 expr->value = size >> 3;
628 expr->ctype = size_t_ctype;
629 return 1;
632 static int evaluate_lvalue_expression(struct expression *expr)
634 // FIXME!
635 return evaluate_expression(expr);
638 static int evaluate_expression_list(struct expression_list *head)
640 if (head) {
641 struct ptr_list *list = (struct ptr_list *)head;
642 do {
643 int i;
644 for (i = 0; i < list->nr; i++) {
645 struct expression *expr = (struct expression *)list->list[i];
646 evaluate_expression(expr);
648 } while ((list = list->next) != (struct ptr_list *)head);
650 // FIXME!
651 return 1;
654 static int evaluate_cast(struct expression *expr)
656 struct expression *target = expr->cast_expression;
657 struct symbol *ctype = expr->cast_type;
659 if (!evaluate_expression(target))
660 return 0;
661 examine_symbol_type(ctype);
662 expr->ctype = ctype;
664 /* Simplify normal integer casts.. */
665 if (target->type == EXPR_VALUE)
666 cast_value(expr, ctype, target, target->ctype);
667 return 1;
670 static int evaluate_call(struct expression *expr)
672 int args, fnargs;
673 struct symbol *ctype;
674 struct expression *fn = expr->fn;
675 struct expression_list *arglist = expr->args;
677 if (!evaluate_expression(fn))
678 return 0;
679 if (!evaluate_expression_list(arglist))
680 return 0;
681 ctype = fn->ctype;
682 if (ctype->type == SYM_PTR)
683 ctype = ctype->ctype.base_type;
684 if (ctype->type != SYM_FN) {
685 warn(expr->token, "not a function");
686 return 0;
688 args = expression_list_size(expr->args);
689 fnargs = symbol_list_size(ctype->arguments);
690 if (args < fnargs)
691 warn(expr->token, "not enough arguments for function");
692 if (args > fnargs && !ctype->variadic)
693 warn(expr->token, "too many arguments for function");
694 expr->ctype = ctype->ctype.base_type;
695 return 1;
698 int evaluate_expression(struct expression *expr)
700 if (!expr)
701 return 0;
702 if (expr->ctype)
703 return 1;
705 switch (expr->type) {
706 case EXPR_CONSTANT:
707 return evaluate_constant(expr);
708 case EXPR_SYMBOL:
709 return evaluate_symbol(expr);
710 case EXPR_BINOP:
711 if (!evaluate_expression(expr->left))
712 return 0;
713 if (!evaluate_expression(expr->right))
714 return 0;
715 return evaluate_binop(expr);
716 case EXPR_COMMA:
717 if (!evaluate_expression(expr->left))
718 return 0;
719 if (!evaluate_expression(expr->right))
720 return 0;
721 return evaluate_comma(expr);
722 case EXPR_COMPARE:
723 if (!evaluate_expression(expr->left))
724 return 0;
725 if (!evaluate_expression(expr->right))
726 return 0;
727 return evaluate_compare(expr);
728 case EXPR_ASSIGNMENT:
729 if (!evaluate_lvalue_expression(expr->left))
730 return 0;
731 if (!evaluate_expression(expr->right))
732 return 0;
733 return evaluate_assignment(expr);
734 case EXPR_PREOP:
735 if (!evaluate_expression(expr->unop))
736 return 0;
737 return evaluate_preop(expr);
738 case EXPR_POSTOP:
739 if (!evaluate_expression(expr->unop))
740 return 0;
741 return evaluate_postop(expr);
742 case EXPR_CAST:
743 return evaluate_cast(expr);
744 case EXPR_SIZEOF:
745 return evaluate_sizeof(expr);
746 case EXPR_DEREF:
747 return evaluate_dereference(expr);
748 case EXPR_CALL:
749 return evaluate_call(expr);
750 default:
751 break;
753 return 0;
756 long long get_expression_value(struct expression *expr)
758 long long left, middle, right;
760 switch (expr->type) {
761 case EXPR_SIZEOF:
762 if (expr->cast_type) {
763 examine_symbol_type(expr->cast_type);
764 if (expr->cast_type->bit_size & 7) {
765 warn(expr->token, "type has no size");
766 return 0;
768 return expr->cast_type->bit_size >> 3;
770 warn(expr->token, "expression sizes not yet supported");
771 return 0;
772 case EXPR_CONSTANT:
773 evaluate_constant(expr);
774 if (expr->type == EXPR_VALUE)
775 return expr->value;
776 return 0;
777 case EXPR_SYMBOL: {
778 struct symbol *sym = expr->symbol;
779 if (!sym || !sym->ctype.base_type || sym->ctype.base_type->type != SYM_ENUM) {
780 warn(expr->token, "undefined identifier in constant expression");
781 return 0;
783 return sym->value;
786 #define OP(x,y) case x: return left y right;
787 case EXPR_BINOP:
788 case EXPR_COMPARE:
789 left = get_expression_value(expr->left);
790 if (!left && expr->op == SPECIAL_LOGICAL_AND)
791 return 0;
792 if (left && expr->op == SPECIAL_LOGICAL_OR)
793 return 1;
794 right = get_expression_value(expr->right);
795 switch (expr->op) {
796 OP('+',+); OP('-',-); OP('*',*); OP('/',/);
797 OP('%',%); OP('<',<); OP('>',>);
798 OP('&',&);OP('|',|);OP('^',^);
799 OP(SPECIAL_EQUAL,==); OP(SPECIAL_NOTEQUAL,!=);
800 OP(SPECIAL_LTE,<=); OP(SPECIAL_LEFTSHIFT,<<);
801 OP(SPECIAL_RIGHTSHIFT,>>); OP(SPECIAL_GTE,>=);
802 OP(SPECIAL_LOGICAL_AND,&&);OP(SPECIAL_LOGICAL_OR,||);
804 break;
806 #undef OP
807 #define OP(x,y) case x: return y left;
808 case EXPR_PREOP:
809 left = get_expression_value(expr->unop);
810 switch (expr->op) {
811 OP('+', +); OP('-', -); OP('!', !); OP('~', ~); OP('(', );
813 break;
815 case EXPR_CONDITIONAL:
816 left = get_expression_value(expr->conditional);
817 if (!expr->cond_true)
818 middle = left;
819 else
820 middle = get_expression_value(expr->cond_true);
821 right = get_expression_value(expr->cond_false);
822 return left ? middle : right;
824 default:
825 break;
827 error(expr->token, "bad constant expression");
828 return 0;