571 snprintf(buf, sizeof(buf), "$%d", alloc_functions[i].param);
572 buf_size_recipe = alloc_sname(buf);
573 return swap_format(expr, buf_size_recipe);
574 }
575 }
576
577 if (sym->ctype.modifiers & MOD_STATIC) {
578 snprintf(sql_filter, 1024, "file = '%s' and function = '%s';",
579 get_filename(), sym->ident->name);
580 } else {
581 snprintf(sql_filter, 1024, "function = '%s' and static = 0;",
582 sym->ident->name);
583 }
584
585 buf_size_recipe = NULL;
586 run_sql(db_buf_size_callback, NULL,
587 "select value from return_states where type=%d and %s",
588 BUF_SIZE, sql_filter);
589 if (!buf_size_recipe || strcmp(buf_size_recipe, "invalid") == 0)
590 return NULL;
591 return swap_format(expr, buf_size_recipe);
592 }
593
594 static void match_call_assignment(struct expression *expr)
595 {
596 char *sname;
597
598 sname = get_allocation_recipe_from_call(expr->right);
599 if (!sname)
600 return;
601 set_state_expr(my_id, expr->left, alloc_state_sname(sname));
602 }
603
604 static void match_returns_call(int return_id, char *return_ranges, struct expression *call)
605 {
606 char *sname;
607
608 sname = get_allocation_recipe_from_call(call);
609 if (option_debug)
610 sm_msg("sname = %s", sname);
611 if (!sname)
612 return;
613
614 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "",
615 sname);
616 }
617
618 static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr)
619 {
620 struct expression *tmp;
621 struct smatch_state *state;
622 struct symbol *sym;
623 char *name;
624 int cnt = 0;
625
626 expr = strip_expr(expr);
627 while ((tmp = get_assigned_expr(expr))) {
628 if (cnt++ > 5) /* assignments to self cause infinite loops */
629 break;
630 expr = strip_expr(tmp);
631 }
632 if (!expr)
633 return;
634
635 if (expr->type == EXPR_CALL) {
636 match_returns_call(return_id, return_ranges, expr);
637 return;
638 }
639
640 name = expr_to_var_sym(expr, &sym);
641 if (!name || !sym)
642 goto free;
643
644 state = get_state(my_id, name, sym);
645 if (!state || !state->data)
646 goto free;
647
648 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "",
649 state->name);
650 free:
651 free_string(name);
652 }
653
654 void register_parse_call_math(int id)
655 {
656 int i;
657
658 my_id = id;
659
660 set_dynamic_states(my_id);
661
662 for (i = 0; i < ARRAY_SIZE(alloc_functions); i++)
663 add_function_assign_hook(alloc_functions[i].func, &match_alloc,
664 INT_PTR(alloc_functions[i].param));
665 add_hook(&match_call_assignment, CALL_ASSIGNMENT_HOOK);
666 add_split_return_callback(print_returned_allocations);
667 }
668
|
571 snprintf(buf, sizeof(buf), "$%d", alloc_functions[i].param);
572 buf_size_recipe = alloc_sname(buf);
573 return swap_format(expr, buf_size_recipe);
574 }
575 }
576
577 if (sym->ctype.modifiers & MOD_STATIC) {
578 snprintf(sql_filter, 1024, "file = '%s' and function = '%s';",
579 get_filename(), sym->ident->name);
580 } else {
581 snprintf(sql_filter, 1024, "function = '%s' and static = 0;",
582 sym->ident->name);
583 }
584
585 buf_size_recipe = NULL;
586 run_sql(db_buf_size_callback, NULL,
587 "select value from return_states where type=%d and %s",
588 BUF_SIZE, sql_filter);
589 if (!buf_size_recipe || strcmp(buf_size_recipe, "invalid") == 0)
590 return NULL;
591 /* Known sizes should be handled in smatch_buf_size.c */
592 if (!strchr(buf_size_recipe, '$'))
593 return NULL;
594 return swap_format(expr, buf_size_recipe);
595 }
596
597 static void match_call_assignment(struct expression *expr)
598 {
599 char *sname;
600
601 sname = get_allocation_recipe_from_call(expr->right);
602 if (!sname)
603 return;
604 set_state_expr(my_id, expr->left, alloc_state_sname(sname));
605 }
606
607 const char *get_allocation_math(struct expression *expr)
608 {
609 struct expression *tmp;
610 struct smatch_state *state;
611 int cnt = 0;
612
613 expr = strip_expr(expr);
614 while ((tmp = get_assigned_expr(expr))) {
615 if (cnt++ > 5) /* assignments to self cause infinite loops */
616 break;
617 expr = strip_expr(tmp);
618 }
619 if (!expr)
620 return NULL;
621
622 if (expr->type == EXPR_CALL)
623 return get_allocation_recipe_from_call(expr);
624
625 state = get_state_expr(my_id, expr);
626 if (!state || !state->data)
627 return NULL;
628
629 return state->name;
630 }
631
632 void register_parse_call_math(int id)
633 {
634 int i;
635
636 my_id = id;
637
638 set_dynamic_states(my_id);
639
640 for (i = 0; i < ARRAY_SIZE(alloc_functions); i++)
641 add_function_assign_hook(alloc_functions[i].func, &match_alloc,
642 INT_PTR(alloc_functions[i].param));
643 add_hook(&match_call_assignment, CALL_ASSIGNMENT_HOOK);
644 }
645
|