511 if (!tag || !arg->ident)
512 return NULL;
513
514 type = get_real_base_type(arg);
515 if (!type)
516 return NULL;
517 if (!star) {
518 if (type->type != SYM_PTR)
519 return NULL;
520 type = get_real_base_type(type);
521 if (!type)
522 return NULL;
523 }
524
525 if (star || type->type == SYM_BASETYPE) {
526 run_sql(save_vals, &db_info,
527 "select value from mtag_data where tag = %lld and offset = %d and type = %d;",
528 tag, arg_offset, DATA_VALUE);
529 } else { /* presumably the parameter is a struct pointer */
530 run_sql(save_vals, &db_info,
531 "select offset, value from mtag_data where tag = %lld and type = %d;",
532 tag, DATA_VALUE);
533 }
534
535 if (db_info.prev_offset != -1)
536 set_param_value(&db_info.stree, arg, db_info.prev_offset, db_info.rl);
537
538 // FIXME: handle an offset correctly
539 if (!star && !arg_offset) {
540 sval_t sval;
541
542 sval.type = get_real_base_type(arg);
543 sval.uvalue = tag;
544 set_state_stree(&db_info.stree, SMATCH_EXTRA, arg->ident->name, arg, alloc_estate_sval(sval));
545 }
546 return db_info.stree;
547 }
548
549 static void load_container_data(struct symbol *arg, const char *info)
550 {
551 mtag_t cur_tag, container_tag, arg_tag;
562 return;
563 *p = '\0';
564 cont = p + 1;
565 p = copy;
566 if (p[0] == '*') {
567 star = 1;
568 p += 2;
569 }
570
571 if (strcmp(cont, "$(-1)") != 0)
572 return;
573
574 if (!get_toplevel_mtag(cur_func_sym, &cur_tag))
575 return;
576
577 while (true) {
578 container_offset = strtoul(p, &p, 0);
579 if (local_debug)
580 sm_msg("%s: cur_tag = %llu container_offset = %d",
581 __func__, cur_tag, container_offset);
582 if (!mtag_map_select_container(cur_tag, container_offset, &container_tag))
583 return;
584 cur_tag = container_tag;
585 if (local_debug)
586 sm_msg("%s: container_tag = %llu p = '%s'",
587 __func__, container_tag, p);
588 if (!p)
589 return;
590 if (p[0] != '-')
591 break;
592 p++;
593 }
594
595 if (p[0] != '+')
596 return;
597
598 p++;
599 arg_offset = strtoul(p, &p, 0);
600 if (p && *p && *p != ')')
601 return;
602
603 if (!arg_offset || star) {
604 arg_tag = container_tag;
605 } else {
606 if (!mtag_map_select_tag(container_tag, -arg_offset, &arg_tag))
607 return;
608 }
609
610 stree = load_tag_info_sym(arg_tag, arg, arg_offset, star);
611 FOR_EACH_SM(stree, sm) {
612 set_state(sm->owner, sm->name, sm->sym, sm->state);
613 } END_FOR_EACH_SM(sm);
614 free_stree(&stree);
615 }
616
617 static void handle_passed_container(struct symbol *sym)
618 {
619 struct symbol *arg;
620 struct smatch_state *state;
621
622 FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
623 state = get_state(param_id, arg->ident->name, arg);
624 if (!state || state == &merged)
625 continue;
626 load_container_data(arg, state->name);
|
511 if (!tag || !arg->ident)
512 return NULL;
513
514 type = get_real_base_type(arg);
515 if (!type)
516 return NULL;
517 if (!star) {
518 if (type->type != SYM_PTR)
519 return NULL;
520 type = get_real_base_type(type);
521 if (!type)
522 return NULL;
523 }
524
525 if (star || type->type == SYM_BASETYPE) {
526 run_sql(save_vals, &db_info,
527 "select value from mtag_data where tag = %lld and offset = %d and type = %d;",
528 tag, arg_offset, DATA_VALUE);
529 } else { /* presumably the parameter is a struct pointer */
530 run_sql(save_vals, &db_info,
531 "select offset, value from mtag_data where tag = %lld and type = %d order by offset;",
532 tag, DATA_VALUE);
533 }
534
535 if (db_info.prev_offset != -1)
536 set_param_value(&db_info.stree, arg, db_info.prev_offset, db_info.rl);
537
538 // FIXME: handle an offset correctly
539 if (!star && !arg_offset) {
540 sval_t sval;
541
542 sval.type = get_real_base_type(arg);
543 sval.uvalue = tag;
544 set_state_stree(&db_info.stree, SMATCH_EXTRA, arg->ident->name, arg, alloc_estate_sval(sval));
545 }
546 return db_info.stree;
547 }
548
549 static void load_container_data(struct symbol *arg, const char *info)
550 {
551 mtag_t cur_tag, container_tag, arg_tag;
562 return;
563 *p = '\0';
564 cont = p + 1;
565 p = copy;
566 if (p[0] == '*') {
567 star = 1;
568 p += 2;
569 }
570
571 if (strcmp(cont, "$(-1)") != 0)
572 return;
573
574 if (!get_toplevel_mtag(cur_func_sym, &cur_tag))
575 return;
576
577 while (true) {
578 container_offset = strtoul(p, &p, 0);
579 if (local_debug)
580 sm_msg("%s: cur_tag = %llu container_offset = %d",
581 __func__, cur_tag, container_offset);
582 if (!mtag_map_select_container(cur_tag, -container_offset, &container_tag))
583 return;
584 cur_tag = container_tag;
585 if (local_debug)
586 sm_msg("%s: container_tag = %llu p = '%s'",
587 __func__, container_tag, p);
588 if (!p)
589 return;
590 if (p[0] != '-')
591 break;
592 p++;
593 }
594
595 if (p[0] != '+')
596 return;
597
598 p++;
599 arg_offset = strtoul(p, &p, 0);
600 if (p && *p && *p != ')')
601 return;
602
603 if (!arg_offset || star) {
604 arg_tag = container_tag;
605 } else {
606 if (!mtag_map_select_tag(container_tag, arg_offset, &arg_tag))
607 return;
608 }
609
610 stree = load_tag_info_sym(arg_tag, arg, arg_offset, star);
611 FOR_EACH_SM(stree, sm) {
612 set_state(sm->owner, sm->name, sm->sym, sm->state);
613 } END_FOR_EACH_SM(sm);
614 free_stree(&stree);
615 }
616
617 static void handle_passed_container(struct symbol *sym)
618 {
619 struct symbol *arg;
620 struct smatch_state *state;
621
622 FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
623 state = get_state(param_id, arg->ident->name, arg);
624 if (!state || state == &merged)
625 continue;
626 load_container_data(arg, state->name);
|