12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 */
17
18 /*
19 * The idea here is that you have an expression and you
20 * want to know what the type is for that.
21 */
22
23 #include "smatch.h"
24 #include "smatch_slist.h"
25
26 struct symbol *get_real_base_type(struct symbol *sym)
27 {
28 struct symbol *ret;
29
30 if (!sym)
31 return NULL;
32 ret = get_base_type(sym);
33 if (!ret)
34 return NULL;
35 if (ret->type == SYM_RESTRICT || ret->type == SYM_NODE)
36 return get_real_base_type(ret);
37 return ret;
38 }
39
40 int type_bytes(struct symbol *type)
41 {
42 int bits;
43
44 if (type && type->type == SYM_ARRAY)
45 return array_bytes(type);
46
47 bits = type_bits(type);
48 if (bits < 0)
49 return 0;
50 return bits_to_bytes(bits);
51 }
58 }
59
60 static struct symbol *get_binop_type(struct expression *expr)
61 {
62 struct symbol *left, *right;
63
64 left = get_type(expr->left);
65 if (!left)
66 return NULL;
67
68 if (expr->op == SPECIAL_LEFTSHIFT ||
69 expr->op == SPECIAL_RIGHTSHIFT) {
70 if (type_positive_bits(left) < 31)
71 return &int_ctype;
72 return left;
73 }
74 right = get_type(expr->right);
75 if (!right)
76 return NULL;
77
78 if (left->type == SYM_PTR || left->type == SYM_ARRAY)
79 return left;
80 if (right->type == SYM_PTR || right->type == SYM_ARRAY)
81 return right;
82
83 if (type_positive_bits(left) < 31 && type_positive_bits(right) < 31)
84 return &int_ctype;
85
86 if (type_positive_bits(left) > type_positive_bits(right))
87 return left;
88 return right;
89 }
90
91 static struct symbol *get_type_symbol(struct expression *expr)
92 {
93 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
94 return NULL;
95
96 return get_real_base_type(expr->symbol);
97 }
252 case EXPR_COMPARE:
253 case EXPR_BINOP:
254 ret = get_binop_type(expr);
255 break;
256 case EXPR_CALL:
257 ret = get_return_type(expr);
258 break;
259 case EXPR_STATEMENT:
260 ret = get_expr_stmt_type(expr->statement);
261 break;
262 case EXPR_CONDITIONAL:
263 case EXPR_SELECT:
264 ret = get_select_type(expr);
265 break;
266 case EXPR_SIZEOF:
267 ret = &ulong_ctype;
268 break;
269 case EXPR_LOGICAL:
270 ret = &int_ctype;
271 break;
272 default:
273 return NULL;
274 }
275
276 if (ret && ret->type == SYM_TYPEOF)
277 ret = get_type(ret->initializer);
278
279 expr->ctype = ret;
280 return ret;
281 }
282
283 static struct symbol *get_final_type_helper(struct expression *expr)
284 {
285 /*
286 * I'm not totally positive I understand types...
287 *
288 * So, when you're doing pointer math, and you do a subtraction, then
289 * the sval_binop() and whatever need to know the type of the pointer
290 * so they can figure out the alignment. But the result is going to be
291 * and ssize_t. So get_operation_type() gives you the pointer type
292 * and get_type() gives you ssize_t.
293 *
294 * Most of the time the operation type and the final type are the same
295 * but this just handles the few places where they are different.
296 *
297 */
298
299 expr = strip_parens(expr);
300 if (!expr)
301 return NULL;
302
303 switch (expr->type) {
304 case EXPR_COMPARE:
305 return &int_ctype;
306 case EXPR_BINOP: {
307 struct symbol *left, *right;
308
309 if (expr->op != '-')
310 return NULL;
311
312 left = get_type(expr->left);
313 right = get_type(expr->right);
314 if (type_is_ptr(left) || type_is_ptr(right))
315 return ssize_t_ctype;
316 }
317 }
318
319 return NULL;
320 }
321
322 struct symbol *get_type(struct expression *expr)
323 {
324 return get_type_helper(expr);
325 }
326
327 struct symbol *get_final_type(struct expression *expr)
328 {
329 struct symbol *ret;
330
331 ret = get_final_type_helper(expr);
332 if (ret)
333 return ret;
334 return get_type_helper(expr);
335 }
336
337 struct symbol *get_promoted_type(struct symbol *left, struct symbol *right)
338 {
339 struct symbol *ret = &int_ctype;
380 if (!sym)
381 return 0;
382 if (type_signed(sym))
383 return 1;
384 return 0;
385 }
386
387 int returns_unsigned(struct symbol *sym)
388 {
389 if (!sym)
390 return 0;
391 sym = get_base_type(sym);
392 if (!sym || sym->type != SYM_FN)
393 return 0;
394 sym = get_base_type(sym);
395 return type_unsigned(sym);
396 }
397
398 int is_pointer(struct expression *expr)
399 {
400 struct symbol *sym;
401
402 sym = get_type(expr);
403 if (!sym)
404 return 0;
405 if (sym == &string_ctype)
406 return 0;
407 if (sym->type == SYM_PTR)
408 return 1;
409 return 0;
410 }
411
412 int returns_pointer(struct symbol *sym)
413 {
414 if (!sym)
415 return 0;
416 sym = get_base_type(sym);
417 if (!sym || sym->type != SYM_FN)
418 return 0;
419 sym = get_base_type(sym);
420 if (sym->type == SYM_PTR)
421 return 1;
422 return 0;
423 }
424
425 sval_t sval_type_max(struct symbol *base_type)
426 {
427 sval_t ret;
428
429 if (!base_type || !type_bits(base_type))
430 base_type = &llong_ctype;
431 ret.type = base_type;
432
433 ret.value = (~0ULL) >> (64 - type_positive_bits(base_type));
434 return ret;
435 }
436
437 sval_t sval_type_min(struct symbol *base_type)
438 {
439 sval_t ret;
440
441 if (!base_type || !type_bits(base_type))
442 base_type = &llong_ctype;
443 ret.type = base_type;
444
445 if (type_unsigned(base_type)) {
446 ret.value = 0;
447 return ret;
448 }
449
450 ret.value = (~0ULL) << type_positive_bits(base_type);
451
452 return ret;
453 }
454
455 int nr_bits(struct expression *expr)
456 {
457 struct symbol *type;
458
459 type = get_type(expr);
460 if (!type)
461 return 0;
462 return type_bits(type);
463 }
464
465 int is_void_pointer(struct expression *expr)
587
588 i = 0;
589 FOR_EACH_PTR(fn_type->arguments, tmp) {
590 arg_type = get_real_base_type(tmp);
591 if (i == arg) {
592 return arg_type;
593 }
594 i++;
595 } END_FOR_EACH_PTR(tmp);
596
597 return NULL;
598 }
599
600 static struct symbol *get_member_from_string(struct symbol_list *symbol_list, const char *name)
601 {
602 struct symbol *tmp, *sub;
603 int chunk_len;
604
605 if (strncmp(name, ".", 1) == 0)
606 name += 1;
607 if (strncmp(name, "->", 2) == 0)
608 name += 2;
609
610 FOR_EACH_PTR(symbol_list, tmp) {
611 if (!tmp->ident) {
612 sub = get_real_base_type(tmp);
613 sub = get_member_from_string(sub->symbol_list, name);
614 if (sub)
615 return sub;
616 continue;
617 }
618
619 if (strcmp(tmp->ident->name, name) == 0)
620 return tmp;
621
622 chunk_len = strlen(tmp->ident->name);
623 if (strncmp(tmp->ident->name, name, chunk_len) == 0 &&
624 (name[chunk_len] == '.' || name[chunk_len] == '-')) {
625 sub = get_real_base_type(tmp);
626 return get_member_from_string(sub->symbol_list, name + chunk_len);
627 }
628
629 } END_FOR_EACH_PTR(tmp);
630
631 return NULL;
632 }
633
634 struct symbol *get_member_type_from_key(struct expression *expr, const char *key)
635 {
636 struct symbol *sym;
637
638 if (strcmp(key, "$") == 0)
639 return get_type(expr);
640
641 if (strcmp(key, "*$") == 0) {
642 sym = get_type(expr);
643 if (!sym || sym->type != SYM_PTR)
644 return NULL;
645 return get_real_base_type(sym);
724
725 static const char *base_type_str(struct symbol *sym)
726 {
727 int i;
728
729 for (i = 0; i < ARRAY_SIZE(base_types); i++) {
730 if (sym == base_types[i].sym)
731 return base_types[i].name;
732 }
733 return "<unknown>";
734 }
735
736 static int type_str_helper(char *buf, int size, struct symbol *type)
737 {
738 int n;
739
740 if (!type)
741 return snprintf(buf, size, "<unknown>");
742
743 if (type->type == SYM_BASETYPE) {
744 return snprintf(buf, size, base_type_str(type));
745 } else if (type->type == SYM_PTR) {
746 type = get_real_base_type(type);
747 n = type_str_helper(buf, size, type);
748 if (n > size)
749 return n;
750 return n + snprintf(buf + n, size - n, "*");
751 } else if (type->type == SYM_ARRAY) {
752 type = get_real_base_type(type);
753 n = type_str_helper(buf, size, type);
754 if (n > size)
755 return n;
756 return n + snprintf(buf + n, size - n, "[]");
757 } else if (type->type == SYM_STRUCT) {
758 return snprintf(buf, size, "struct %s", type->ident ? type->ident->name : "");
759 } else if (type->type == SYM_UNION) {
760 if (type->ident)
761 return snprintf(buf, size, "union %s", type->ident->name);
762 else
763 return snprintf(buf, size, "anonymous union");
764 } else if (type->type == SYM_FN) {
778 if (i++)
779 n += snprintf(buf + n, size - n, ", ");
780 if (n > size)
781 return n;
782 arg_type = get_real_base_type(arg);
783 n += type_str_helper(buf + n, size - n, arg_type);
784 if (n > size)
785 return n;
786 } END_FOR_EACH_PTR(arg);
787
788 return n + snprintf(buf + n, size - n, ")");
789 } else if (type->type == SYM_NODE) {
790 n = snprintf(buf, size, "node {");
791 if (n > size)
792 return n;
793 type = get_real_base_type(type);
794 n += type_str_helper(buf + n, size - n, type);
795 if (n > size)
796 return n;
797 return n + snprintf(buf + n, size - n, "}");
798 } else {
799 return snprintf(buf, size, "<type %d>", type->type);
800 }
801 }
802
803 char *type_to_str(struct symbol *type)
804 {
805 static char buf[256];
806
807 buf[0] = '\0';
808 type_str_helper(buf, sizeof(buf), type);
809 return buf;
810 }
|
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 */
17
18 /*
19 * The idea here is that you have an expression and you
20 * want to know what the type is for that.
21 */
22
23 #include "smatch.h"
24 #include "smatch_slist.h"
25
26 struct symbol *get_real_base_type(struct symbol *sym)
27 {
28 struct symbol *ret;
29
30 if (!sym)
31 return NULL;
32 if (sym->type == SYM_BASETYPE)
33 return sym;
34 ret = get_base_type(sym);
35 if (!ret)
36 return NULL;
37 if (ret->type == SYM_RESTRICT || ret->type == SYM_NODE)
38 return get_real_base_type(ret);
39 return ret;
40 }
41
42 int type_bytes(struct symbol *type)
43 {
44 int bits;
45
46 if (type && type->type == SYM_ARRAY)
47 return array_bytes(type);
48
49 bits = type_bits(type);
50 if (bits < 0)
51 return 0;
52 return bits_to_bytes(bits);
53 }
60 }
61
62 static struct symbol *get_binop_type(struct expression *expr)
63 {
64 struct symbol *left, *right;
65
66 left = get_type(expr->left);
67 if (!left)
68 return NULL;
69
70 if (expr->op == SPECIAL_LEFTSHIFT ||
71 expr->op == SPECIAL_RIGHTSHIFT) {
72 if (type_positive_bits(left) < 31)
73 return &int_ctype;
74 return left;
75 }
76 right = get_type(expr->right);
77 if (!right)
78 return NULL;
79
80 if (expr->op == '-' &&
81 (is_ptr_type(left) && is_ptr_type(right)))
82 return ssize_t_ctype;
83
84 if (left->type == SYM_PTR || left->type == SYM_ARRAY)
85 return left;
86 if (right->type == SYM_PTR || right->type == SYM_ARRAY)
87 return right;
88
89 if (type_positive_bits(left) < 31 && type_positive_bits(right) < 31)
90 return &int_ctype;
91
92 if (type_positive_bits(left) > type_positive_bits(right))
93 return left;
94 return right;
95 }
96
97 static struct symbol *get_type_symbol(struct expression *expr)
98 {
99 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
100 return NULL;
101
102 return get_real_base_type(expr->symbol);
103 }
258 case EXPR_COMPARE:
259 case EXPR_BINOP:
260 ret = get_binop_type(expr);
261 break;
262 case EXPR_CALL:
263 ret = get_return_type(expr);
264 break;
265 case EXPR_STATEMENT:
266 ret = get_expr_stmt_type(expr->statement);
267 break;
268 case EXPR_CONDITIONAL:
269 case EXPR_SELECT:
270 ret = get_select_type(expr);
271 break;
272 case EXPR_SIZEOF:
273 ret = &ulong_ctype;
274 break;
275 case EXPR_LOGICAL:
276 ret = &int_ctype;
277 break;
278 case EXPR_OFFSETOF:
279 ret = &ulong_ctype;
280 break;
281 default:
282 return NULL;
283 }
284
285 if (ret && ret->type == SYM_TYPEOF)
286 ret = get_type(ret->initializer);
287
288 expr->ctype = ret;
289 return ret;
290 }
291
292 static struct symbol *get_final_type_helper(struct expression *expr)
293 {
294 /*
295 * The problem is that I wrote a bunch of Smatch to think that
296 * you could do get_type() on an expression and it would give
297 * you what the comparison was type promoted to. This is wrong
298 * but fixing it is a big of work... Hence this horrible hack.
299 *
300 */
301
302 expr = strip_parens(expr);
303 if (!expr)
304 return NULL;
305
306 if (expr->type == EXPR_COMPARE)
307 return &int_ctype;
308
309 return NULL;
310 }
311
312 struct symbol *get_type(struct expression *expr)
313 {
314 return get_type_helper(expr);
315 }
316
317 struct symbol *get_final_type(struct expression *expr)
318 {
319 struct symbol *ret;
320
321 ret = get_final_type_helper(expr);
322 if (ret)
323 return ret;
324 return get_type_helper(expr);
325 }
326
327 struct symbol *get_promoted_type(struct symbol *left, struct symbol *right)
328 {
329 struct symbol *ret = &int_ctype;
370 if (!sym)
371 return 0;
372 if (type_signed(sym))
373 return 1;
374 return 0;
375 }
376
377 int returns_unsigned(struct symbol *sym)
378 {
379 if (!sym)
380 return 0;
381 sym = get_base_type(sym);
382 if (!sym || sym->type != SYM_FN)
383 return 0;
384 sym = get_base_type(sym);
385 return type_unsigned(sym);
386 }
387
388 int is_pointer(struct expression *expr)
389 {
390 return type_is_ptr(get_type(expr));
391 }
392
393 int returns_pointer(struct symbol *sym)
394 {
395 if (!sym)
396 return 0;
397 sym = get_base_type(sym);
398 if (!sym || sym->type != SYM_FN)
399 return 0;
400 sym = get_base_type(sym);
401 if (sym->type == SYM_PTR)
402 return 1;
403 return 0;
404 }
405
406 sval_t sval_type_max(struct symbol *base_type)
407 {
408 sval_t ret;
409
410 if (!base_type || !type_bits(base_type))
411 base_type = &llong_ctype;
412 ret.type = base_type;
413
414 ret.value = (~0ULL) >> (64 - type_positive_bits(base_type));
415 return ret;
416 }
417
418 sval_t sval_type_min(struct symbol *base_type)
419 {
420 sval_t ret;
421
422 if (!base_type || !type_bits(base_type))
423 base_type = &llong_ctype;
424 ret.type = base_type;
425
426 if (type_unsigned(base_type) || is_ptr_type(base_type)) {
427 ret.value = 0;
428 return ret;
429 }
430
431 ret.value = (~0ULL) << type_positive_bits(base_type);
432
433 return ret;
434 }
435
436 int nr_bits(struct expression *expr)
437 {
438 struct symbol *type;
439
440 type = get_type(expr);
441 if (!type)
442 return 0;
443 return type_bits(type);
444 }
445
446 int is_void_pointer(struct expression *expr)
568
569 i = 0;
570 FOR_EACH_PTR(fn_type->arguments, tmp) {
571 arg_type = get_real_base_type(tmp);
572 if (i == arg) {
573 return arg_type;
574 }
575 i++;
576 } END_FOR_EACH_PTR(tmp);
577
578 return NULL;
579 }
580
581 static struct symbol *get_member_from_string(struct symbol_list *symbol_list, const char *name)
582 {
583 struct symbol *tmp, *sub;
584 int chunk_len;
585
586 if (strncmp(name, ".", 1) == 0)
587 name += 1;
588 else if (strncmp(name, "->", 2) == 0)
589 name += 2;
590
591 FOR_EACH_PTR(symbol_list, tmp) {
592 if (!tmp->ident) {
593 sub = get_real_base_type(tmp);
594 sub = get_member_from_string(sub->symbol_list, name);
595 if (sub)
596 return sub;
597 continue;
598 }
599
600 if (strcmp(tmp->ident->name, name) == 0)
601 return tmp;
602
603 chunk_len = tmp->ident->len;
604 if (strncmp(tmp->ident->name, name, chunk_len) == 0 &&
605 (name[chunk_len] == '.' || name[chunk_len] == '-')) {
606 sub = get_real_base_type(tmp);
607 if (sub->type == SYM_PTR)
608 sub = get_real_base_type(sub);
609 return get_member_from_string(sub->symbol_list, name + chunk_len);
610 }
611
612 } END_FOR_EACH_PTR(tmp);
613
614 return NULL;
615 }
616
617 struct symbol *get_member_type_from_key(struct expression *expr, const char *key)
618 {
619 struct symbol *sym;
620
621 if (strcmp(key, "$") == 0)
622 return get_type(expr);
623
624 if (strcmp(key, "*$") == 0) {
625 sym = get_type(expr);
626 if (!sym || sym->type != SYM_PTR)
627 return NULL;
628 return get_real_base_type(sym);
707
708 static const char *base_type_str(struct symbol *sym)
709 {
710 int i;
711
712 for (i = 0; i < ARRAY_SIZE(base_types); i++) {
713 if (sym == base_types[i].sym)
714 return base_types[i].name;
715 }
716 return "<unknown>";
717 }
718
719 static int type_str_helper(char *buf, int size, struct symbol *type)
720 {
721 int n;
722
723 if (!type)
724 return snprintf(buf, size, "<unknown>");
725
726 if (type->type == SYM_BASETYPE) {
727 return snprintf(buf, size, "%s", base_type_str(type));
728 } else if (type->type == SYM_PTR) {
729 type = get_real_base_type(type);
730 n = type_str_helper(buf, size, type);
731 if (n > size)
732 return n;
733 return n + snprintf(buf + n, size - n, "*");
734 } else if (type->type == SYM_ARRAY) {
735 type = get_real_base_type(type);
736 n = type_str_helper(buf, size, type);
737 if (n > size)
738 return n;
739 return n + snprintf(buf + n, size - n, "[]");
740 } else if (type->type == SYM_STRUCT) {
741 return snprintf(buf, size, "struct %s", type->ident ? type->ident->name : "");
742 } else if (type->type == SYM_UNION) {
743 if (type->ident)
744 return snprintf(buf, size, "union %s", type->ident->name);
745 else
746 return snprintf(buf, size, "anonymous union");
747 } else if (type->type == SYM_FN) {
761 if (i++)
762 n += snprintf(buf + n, size - n, ", ");
763 if (n > size)
764 return n;
765 arg_type = get_real_base_type(arg);
766 n += type_str_helper(buf + n, size - n, arg_type);
767 if (n > size)
768 return n;
769 } END_FOR_EACH_PTR(arg);
770
771 return n + snprintf(buf + n, size - n, ")");
772 } else if (type->type == SYM_NODE) {
773 n = snprintf(buf, size, "node {");
774 if (n > size)
775 return n;
776 type = get_real_base_type(type);
777 n += type_str_helper(buf + n, size - n, type);
778 if (n > size)
779 return n;
780 return n + snprintf(buf + n, size - n, "}");
781 } else if (type->type == SYM_ENUM) {
782 return snprintf(buf, size, "enum %s", type->ident ? type->ident->name : "<unknown>");
783 } else {
784 return snprintf(buf, size, "<type %d>", type->type);
785 }
786 }
787
788 char *type_to_str(struct symbol *type)
789 {
790 static char buf[256];
791
792 buf[0] = '\0';
793 type_str_helper(buf, sizeof(buf), type);
794 return buf;
795 }
|