Print this page
12166 resync smatch to 0.6.1-rc1-il-3

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_db.c
          +++ new/usr/src/tools/smatch/src/smatch_db.c
↓ open down ↓ 19 lines elided ↑ open up ↑
  20   20  #include <unistd.h>
  21   21  #include <ctype.h>
  22   22  #include "smatch.h"
  23   23  #include "smatch_slist.h"
  24   24  #include "smatch_extra.h"
  25   25  
  26   26  struct sqlite3 *smatch_db;
  27   27  struct sqlite3 *mem_db;
  28   28  struct sqlite3 *cache_db;
  29   29  
       30 +int debug_db;
       31 +
  30   32  static int return_id;
  31   33  
       34 +static void call_return_state_hooks(struct expression *expr);
       35 +
  32   36  #define SQLITE_CACHE_PAGES 1000
  33   37  
  34   38  struct def_callback {
  35   39          int hook_type;
  36   40          void (*callback)(const char *name, struct symbol *sym, char *key, char *value);
  37   41  };
  38   42  ALLOCATOR(def_callback, "definition db hook callbacks");
  39   43  DECLARE_PTR_LIST(callback_list, struct def_callback);
  40   44  static struct callback_list *select_caller_info_callbacks;
  41   45  
↓ open down ↓ 56 lines elided ↑ open up ↑
  98  102                  buf[j - 1] = '\0';
  99  103          return alloc_sname(buf);
 100  104  }
 101  105  
 102  106  static int print_sql_output(void *unused, int argc, char **argv, char **azColName)
 103  107  {
 104  108          int i;
 105  109  
 106  110          for (i = 0; i < argc; i++) {
 107  111                  if (i != 0)
 108      -                        printf(", ");
      112 +                        sm_printf(", ");
 109  113                  sm_printf("%s", argv[i]);
 110  114          }
 111  115          sm_printf("\n");
 112  116          return 0;
 113  117  }
 114  118  
 115  119  void sql_exec(struct sqlite3 *db, int (*callback)(void*, int, char**, char**), void *data, const char *sql)
 116  120  {
 117  121          char *err = NULL;
 118  122          int rc;
 119  123  
 120  124          if (!db)
 121  125                  return;
 122  126  
 123      -        if (option_debug) {
      127 +        if (option_debug || debug_db) {
 124  128                  sm_msg("%s", sql);
 125  129                  if (strncasecmp(sql, "select", strlen("select")) == 0)
 126  130                          sqlite3_exec(db, sql, print_sql_output, NULL, NULL);
 127  131          }
 128  132  
 129  133          rc = sqlite3_exec(db, sql, callback, data, &err);
 130  134          if (rc != SQLITE_OK && !parse_error) {
 131  135                  sm_ierror("%s:%d SQL error #2: %s\n", get_filename(), get_lineno(), err);
 132  136                  sm_ierror("%s:%d SQL: '%s'\n", get_filename(), get_lineno(), sql);
 133  137                  parse_error = 1;
↓ open down ↓ 660 lines elided ↑ open up ↑
 794  798                  if (size >= sizeof(buf))
 795  799                          return 0;
 796  800                  memcpy(buf, p, size);
 797  801                  buf[size] = '\0';
 798  802                  if (strstr(next, buf))
 799  803                          return 1;
 800  804                  p = next;
 801  805          }
 802  806  }
 803  807  
      808 +char *sm_to_arg_name(struct expression *expr, struct sm_state *sm)
      809 +{
      810 +        struct symbol *sym;
      811 +        const char *sm_name;
      812 +        char *name;
      813 +        bool is_address = false;
      814 +        bool add_star = false;
      815 +        char buf[256];
      816 +        char *ret = NULL;
      817 +        int len;
      818 +
      819 +        expr = strip_expr(expr);
      820 +        if (!expr)
      821 +                return NULL;
      822 +
      823 +        if (expr->type == EXPR_PREOP && expr->op == '&') {
      824 +                expr = strip_expr(expr->unop);
      825 +                is_address = true;
      826 +        }
      827 +
      828 +        name = expr_to_var_sym(expr, &sym);
      829 +        if (!name || !sym)
      830 +                goto free;
      831 +        if (sym != sm->sym)
      832 +                goto free;
      833 +
      834 +        sm_name = sm->name;
      835 +        add_star = false;
      836 +        if (sm_name[0] == '*') {
      837 +                add_star = true;
      838 +                sm_name++;
      839 +        }
      840 +
      841 +        len = strlen(name);
      842 +        if (strncmp(name, sm_name, len) != 0)
      843 +                goto free;
      844 +        if (sm_name[len] == '\0') {
      845 +                snprintf(buf, sizeof(buf), "%s%s$",
      846 +                         add_star ? "*" : "", is_address ? "*" : "");
      847 +        } else {
      848 +                if (sm_name[len] != '.' && sm_name[len] != '-')
      849 +                        goto free;
      850 +                if (sm_name[len] == '-')
      851 +                        len++;
      852 +                // FIXME does is_address really imply that sm_name[len] == '-'
      853 +                snprintf(buf, sizeof(buf), "%s$->%s", add_star ? "*" : "",
      854 +                         sm_name + len);
      855 +        }
      856 +
      857 +        ret = alloc_sname(buf);
      858 +free:
      859 +        free_string(name);
      860 +        return ret;
      861 +}
      862 +
 804  863  static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
 805  864          void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 806  865  {
 807  866          struct sm_state *sm;
 808  867          const char *sm_name;
 809  868          char *name;
 810  869          struct symbol *sym;
 811  870          int len;
 812  871          char printed_name[256];
 813  872          int is_address = 0;
↓ open down ↓ 596 lines elided ↑ open up ↑
1410 1469          }
1411 1470  
1412 1471          return return_ranges;
1413 1472  }
1414 1473  
1415 1474  static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
1416 1475  {
1417 1476          sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
1418 1477  }
1419 1478  
1420      -static void call_return_state_hooks_conditional(struct expression *expr)
     1479 +static bool call_return_state_hooks_conditional(struct expression *expr)
1421 1480  {
1422      -        struct returned_state_callback *cb;
1423      -        struct range_list *rl;
1424      -        const char *return_ranges;
1425 1481          int final_pass_orig = final_pass;
     1482 +        static int recurse;
1426 1483  
     1484 +        if (recurse >= 2)
     1485 +                return false;
     1486 +        if (!expr ||
     1487 +            (expr->type != EXPR_CONDITIONAL && expr->type != EXPR_SELECT))
     1488 +                return false;
     1489 +
     1490 +        recurse++;
     1491 +
1427 1492          __push_fake_cur_stree();
1428 1493  
1429 1494          final_pass = 0;
1430 1495          __split_whole_condition(expr->conditional);
1431 1496          final_pass = final_pass_orig;
1432 1497  
1433      -        return_ranges = get_return_ranges_str(expr->cond_true ?: expr->conditional, &rl);
     1498 +        call_return_state_hooks(expr->cond_true ?: expr->conditional);
1434 1499  
1435      -        set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1436      -
1437      -        return_id++;
1438      -        FOR_EACH_PTR(returned_state_callbacks, cb) {
1439      -                cb->callback(return_id, (char *)return_ranges, expr->cond_true);
1440      -        } END_FOR_EACH_PTR(cb);
1441      -
1442 1500          __push_true_states();
1443 1501          __use_false_states();
1444 1502  
1445      -        return_ranges = get_return_ranges_str(expr->cond_false, &rl);
1446      -        set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
     1503 +        call_return_state_hooks(expr->cond_false);
1447 1504  
1448      -        return_id++;
1449      -        FOR_EACH_PTR(returned_state_callbacks, cb) {
1450      -                cb->callback(return_id, (char *)return_ranges, expr->cond_false);
1451      -        } END_FOR_EACH_PTR(cb);
1452      -
1453 1505          __merge_true_states();
1454 1506          __free_fake_cur_stree();
     1507 +
     1508 +        recurse--;
     1509 +        return true;
1455 1510  }
1456 1511  
1457 1512  static void call_return_state_hooks_compare(struct expression *expr)
1458 1513  {
1459 1514          struct returned_state_callback *cb;
1460 1515          char *return_ranges;
1461 1516          int final_pass_orig = final_pass;
1462 1517          sval_t sval = { .type = &int_ctype };
1463 1518          sval_t ret;
1464 1519  
↓ open down ↓ 64 lines elided ↑ open up ↑
1529 1584                  return 0;
1530 1585  
1531 1586          if (too_many_possible(sm))
1532 1587                  return 0;
1533 1588  
1534 1589          /* bail if it gets too complicated */
1535 1590          nr_possible = 0;
1536 1591          FOR_EACH_PTR(sm->possible, tmp) {
1537 1592                  if (tmp->merged)
1538 1593                          continue;
     1594 +                if (ptr_in_list(tmp, already_handled))
     1595 +                        continue;
     1596 +                add_ptr_list(&already_handled, tmp);
1539 1597                  nr_possible++;
1540 1598          } END_FOR_EACH_PTR(tmp);
     1599 +        free_slist(&already_handled);
1541 1600          nr_states = get_db_state_count();
1542 1601          if (nr_states * nr_possible >= 2000)
1543 1602                  return 0;
1544 1603  
1545 1604          FOR_EACH_PTR(sm->possible, tmp) {
1546 1605                  if (tmp->merged)
1547 1606                          continue;
1548 1607                  if (ptr_in_list(tmp, already_handled))
1549 1608                          continue;
1550 1609                  add_ptr_list(&already_handled, tmp);
↓ open down ↓ 35 lines elided ↑ open up ↑
1586 1645                  return 0;
1587 1646  
1588 1647          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1589 1648          return split_possible_helper(sm, expr);
1590 1649  }
1591 1650  
1592 1651  static bool has_possible_negative(struct sm_state *sm)
1593 1652  {
1594 1653          struct sm_state *tmp;
1595 1654  
     1655 +        if (!type_signed(estate_type(sm->state)))
     1656 +                return false;
     1657 +
1596 1658          FOR_EACH_PTR(sm->possible, tmp) {
1597 1659                  if (!estate_rl(tmp->state))
1598 1660                          continue;
1599 1661                  if (sval_is_negative(estate_min(tmp->state)) &&
1600 1662                      sval_is_negative(estate_max(tmp->state)))
1601 1663                          return true;
1602 1664          } END_FOR_EACH_PTR(tmp);
1603 1665  
1604 1666          return false;
1605 1667  }
1606 1668  
1607      -static bool has_possible_zero_null(struct sm_state *sm)
     1669 +static bool has_separate_zero_null(struct sm_state *sm)
1608 1670  {
1609 1671          struct sm_state *tmp;
1610 1672          sval_t sval;
1611 1673  
1612 1674          FOR_EACH_PTR(sm->possible, tmp) {
1613 1675                  if (!estate_get_single_value(tmp->state, &sval))
1614 1676                          continue;
1615 1677                  if (sval.value == 0)
1616 1678                          return true;
1617 1679          } END_FOR_EACH_PTR(tmp);
↓ open down ↓ 1 lines elided ↑ open up ↑
1619 1681          return false;
1620 1682  }
1621 1683  
1622 1684  static int split_positive_from_negative(struct expression *expr)
1623 1685  {
1624 1686          struct sm_state *sm;
1625 1687          struct returned_state_callback *cb;
1626 1688          struct range_list *rl;
1627 1689          const char *return_ranges;
1628 1690          struct range_list *ret_rl;
     1691 +        bool separate_zero;
1629 1692          int undo;
1630      -        bool has_zero;
1631 1693  
1632 1694          /* We're going to print the states 3 times */
1633 1695          if (get_db_state_count() > 10000 / 3)
1634 1696                  return 0;
1635 1697  
1636 1698          if (!get_implied_rl(expr, &rl) || !rl)
1637 1699                  return 0;
1638      -        if (is_whole_rl(rl) || is_whole_rl_non_zero(rl))
1639      -                return 0;
1640 1700          /* Forget about INT_MAX and larger */
1641 1701          if (rl_max(rl).value <= 0)
1642 1702                  return 0;
1643 1703          if (!sval_is_negative(rl_min(rl)))
1644 1704                  return 0;
1645 1705  
1646 1706          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1647 1707          if (!sm)
1648 1708                  return 0;
1649 1709          if (!has_possible_negative(sm))
1650 1710                  return 0;
1651      -        has_zero = has_possible_zero_null(sm);
     1711 +        separate_zero = has_separate_zero_null(sm);
1652 1712  
1653      -        if (!assume(compare_expression(expr, has_zero ? '>' : SPECIAL_GTE, zero_expr())))
     1713 +        if (!assume(compare_expression(expr, separate_zero ? '>' : SPECIAL_GTE, zero_expr())))
1654 1714                  return 0;
1655 1715  
1656 1716          return_id++;
1657 1717          return_ranges = get_return_ranges_str(expr, &ret_rl);
1658 1718          set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1659 1719          FOR_EACH_PTR(returned_state_callbacks, cb) {
1660 1720                  cb->callback(return_id, (char *)return_ranges, expr);
1661 1721          } END_FOR_EACH_PTR(cb);
1662 1722  
1663 1723          end_assume();
1664 1724  
1665      -        if (has_zero) {
     1725 +        if (separate_zero) {
1666 1726                  undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
1667 1727  
1668 1728                  return_id++;
1669 1729                  return_ranges = get_return_ranges_str(expr, &ret_rl);
1670 1730                  set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1671 1731                  FOR_EACH_PTR(returned_state_callbacks, cb) {
1672 1732                          cb->callback(return_id, (char *)return_ranges, expr);
1673 1733                  } END_FOR_EACH_PTR(cb);
1674 1734  
1675 1735                  if (undo)
↓ open down ↓ 36 lines elided ↑ open up ↑
1712 1772          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1713 1773          if (!sm)
1714 1774                  return 0;
1715 1775          if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1716 1776                  return 0;
1717 1777          state = sm->state;
1718 1778          if (!estate_rl(state))
1719 1779                  return 0;
1720 1780          if (estate_min(state).value == 0 && estate_max(state).value == 0)
1721 1781                  return 0;
1722      -        if (!has_possible_zero_null(sm))
     1782 +        if (!has_separate_zero_null(sm))
1723 1783                  return 0;
1724 1784  
1725 1785          nr_states = get_db_state_count();
1726 1786          if (option_info && nr_states >= 1500)
1727 1787                  return 0;
1728 1788  
1729 1789          rl = estate_rl(state);
1730 1790  
1731 1791          __push_fake_cur_stree();
1732 1792  
↓ open down ↓ 21 lines elided ↑ open up ↑
1754 1814          FOR_EACH_PTR(returned_state_callbacks, cb) {
1755 1815                  cb->callback(return_id, return_ranges, expr);
1756 1816          } END_FOR_EACH_PTR(cb);
1757 1817  
1758 1818          __merge_true_states();
1759 1819          __free_fake_cur_stree();
1760 1820  
1761 1821          return 1;
1762 1822  }
1763 1823  
     1824 +static bool is_kernel_success_fail(struct sm_state *sm)
     1825 +{
     1826 +        struct sm_state *tmp;
     1827 +        struct range_list *rl;
     1828 +        bool has_zero = false;
     1829 +        bool has_neg = false;
     1830 +
     1831 +        if (!type_signed(estate_type(sm->state)))
     1832 +                return false;
     1833 +
     1834 +        FOR_EACH_PTR(sm->possible, tmp) {
     1835 +                rl = estate_rl(tmp->state);
     1836 +                if (!rl)
     1837 +                        return false;
     1838 +                if (rl_min(rl).value == 0 && rl_max(rl).value == 0) {
     1839 +                        has_zero = true;
     1840 +                        continue;
     1841 +                }
     1842 +                has_neg = true;
     1843 +                if (rl_min(rl).value >= -4095 && rl_max(rl).value < 0)
     1844 +                        continue;
     1845 +                if (strcmp(tmp->state->name, "s32min-(-1)") == 0)
     1846 +                        continue;
     1847 +                if (strcmp(tmp->state->name, "s32min-(-1),1-s32max") == 0)
     1848 +                        continue;
     1849 +                return false;
     1850 +        } END_FOR_EACH_PTR(tmp);
     1851 +
     1852 +        return has_zero && has_neg;
     1853 +}
     1854 +
1764 1855  static int call_return_state_hooks_split_success_fail(struct expression *expr)
1765 1856  {
1766 1857          struct sm_state *sm;
1767 1858          struct range_list *rl;
1768 1859          struct range_list *nonzero_rl;
1769 1860          sval_t zero_sval;
1770 1861          struct range_list *zero_rl = NULL;
1771 1862          int nr_states;
1772 1863          struct returned_state_callback *cb;
1773 1864          char *return_ranges;
1774 1865          int final_pass_orig = final_pass;
1775 1866  
1776 1867          if (option_project != PROJ_KERNEL)
1777 1868                  return 0;
1778 1869  
1779 1870          nr_states = get_db_state_count();
1780      -        if (nr_states > 1500)
     1871 +        if (nr_states > 2000)
1781 1872                  return 0;
1782 1873  
1783 1874          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1784 1875          if (!sm)
1785 1876                  return 0;
1786 1877          if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1787 1878                  return 0;
     1879 +        if (!is_kernel_success_fail(sm))
     1880 +                return 0;
1788 1881  
1789 1882          rl = estate_rl(sm->state);
1790 1883          if (!rl)
1791 1884                  return 0;
1792 1885  
1793      -        if (rl_min(rl).value < -4095 || rl_min(rl).value >= 0)
1794      -                return 0;
1795      -        if (rl_max(rl).value != 0)
1796      -                return 0;
1797      -        if (!has_possible_zero_null(sm))
1798      -                return 0;
1799      -
1800 1886          __push_fake_cur_stree();
1801 1887  
1802 1888          final_pass = 0;
1803 1889          __split_whole_condition(expr);
1804 1890          final_pass = final_pass_orig;
1805 1891  
1806 1892          nonzero_rl = rl_filter(rl, rl_zero());
1807 1893          nonzero_rl = cast_rl(cur_func_return_type(), nonzero_rl);
1808 1894          return_ranges = show_rl(nonzero_rl);
1809 1895          set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(nonzero_rl));
↓ open down ↓ 25 lines elided ↑ open up ↑
1835 1921  {
1836 1922          struct range_list *rl;
1837 1923  
1838 1924          if (!get_implied_rl(expr, &rl))
1839 1925                  return 0;
1840 1926          if (rl_min(rl).value == 0 && rl_max(rl).value == 1)
1841 1927                  return 1;
1842 1928          return 0;
1843 1929  }
1844 1930  
1845      -static int is_conditional(struct expression *expr)
1846      -{
1847      -        if (!expr)
1848      -                return 0;
1849      -        if (expr->type == EXPR_CONDITIONAL || expr->type == EXPR_SELECT)
1850      -                return 1;
1851      -        return 0;
1852      -}
1853      -
1854 1931  static int splitable_function_call(struct expression *expr)
1855 1932  {
1856 1933          struct sm_state *sm;
1857 1934          char buf[64];
1858 1935  
1859 1936          if (!expr || expr->type != EXPR_CALL)
1860 1937                  return 0;
1861 1938          snprintf(buf, sizeof(buf), "return %p", expr);
1862 1939          sm = get_sm_state(SMATCH_EXTRA, buf, NULL);
1863 1940          return split_possible_helper(sm, expr);
↓ open down ↓ 37 lines elided ↑ open up ↑
1901 1978          return sm;
1902 1979  }
1903 1980  
1904 1981  static int split_on_bool_sm(struct sm_state *sm, struct expression *expr)
1905 1982  {
1906 1983          struct returned_state_callback *cb;
1907 1984          struct range_list *ret_rl;
1908 1985          const char *return_ranges;
1909 1986          struct sm_state *tmp;
1910 1987          int ret = 0;
1911      -        int nr_possible, nr_states;
1912 1988          struct state_list *already_handled = NULL;
1913 1989  
1914 1990          if (!sm || !sm->merged)
1915 1991                  return 0;
1916 1992  
1917 1993          if (too_many_possible(sm))
1918 1994                  return 0;
1919 1995  
1920      -        /* bail if it gets too complicated */
1921      -        nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
1922      -        nr_states = get_db_state_count();
1923      -        if (nr_states * nr_possible >= 2000)
1924      -                return 0;
1925      -
1926 1996          FOR_EACH_PTR(sm->possible, tmp) {
1927 1997                  if (tmp->merged)
1928 1998                          continue;
1929 1999                  if (ptr_in_list(tmp, already_handled))
1930 2000                          continue;
1931 2001                  add_ptr_list(&already_handled, tmp);
1932 2002  
1933 2003                  ret = 1;
1934 2004                  __push_fake_cur_stree();
1935 2005  
↓ open down ↓ 18 lines elided ↑ open up ↑
1954 2024  {
1955 2025          struct sm_state *start_sm, *sm;
1956 2026          sval_t sval;
1957 2027  
1958 2028          start_sm = find_bool_param();
1959 2029          if (!start_sm)
1960 2030                  return 0;
1961 2031          sm = get_sm_state(SMATCH_EXTRA, start_sm->name, start_sm->sym);
1962 2032          if (!sm || estate_get_single_value(sm->state, &sval))
1963 2033                  return 0;
     2034 +
     2035 +        if (get_db_state_count() * 2 >= 2000)
     2036 +                return 0;
     2037 +
1964 2038          return split_on_bool_sm(sm, expr);
1965 2039  }
1966 2040  
1967 2041  static int split_by_null_nonnull_param(struct expression *expr)
1968 2042  {
1969 2043          struct symbol *arg;
1970 2044          struct sm_state *sm;
1971      -        sval_t zero = {
1972      -                .type = &ulong_ctype,
1973      -        };
     2045 +        int nr_possible;
1974 2046  
1975 2047          /* function must only take one pointer */
1976 2048          if (ptr_list_size((struct ptr_list *)cur_func_sym->ctype.base_type->arguments) != 1)
1977 2049                  return 0;
1978 2050          arg = first_ptr_list((struct ptr_list *)cur_func_sym->ctype.base_type->arguments);
1979 2051          if (!arg->ident)
1980 2052                  return 0;
1981 2053          if (get_real_base_type(arg)->type != SYM_PTR)
1982 2054                  return 0;
1983 2055  
1984 2056          if (param_was_set_var_sym(arg->ident->name, arg))
1985 2057                  return 0;
1986 2058          sm = get_sm_state(SMATCH_EXTRA, arg->ident->name, arg);
1987 2059          if (!sm)
1988 2060                  return 0;
1989 2061  
1990      -        if (!rl_has_sval(estate_rl(sm->state), zero))
     2062 +        if (!has_separate_zero_null(sm))
1991 2063                  return 0;
1992 2064  
     2065 +        nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
     2066 +        if (get_db_state_count() * nr_possible >= 2000)
     2067 +                return 0;
     2068 +
1993 2069          return split_on_bool_sm(sm, expr);
1994 2070  }
1995 2071  
1996 2072  struct expression *strip_expr_statement(struct expression *expr)
1997 2073  {
1998 2074          struct expression *orig = expr;
1999 2075          struct statement *stmt, *last_stmt;
2000 2076  
2001 2077          if (!expr)
2002 2078                  return NULL;
↓ open down ↓ 28 lines elided ↑ open up ↑
2031 2107          expr = strip_expr_statement(expr);
2032 2108  
2033 2109          if (is_impossible_path())
2034 2110                  goto vanilla;
2035 2111  
2036 2112          if (expr && (expr->type == EXPR_COMPARE ||
2037 2113                       !get_implied_value(expr, &sval)) &&
2038 2114              (is_condition(expr) || is_boolean(expr))) {
2039 2115                  call_return_state_hooks_compare(expr);
2040 2116                  return;
2041      -        } else if (is_conditional(expr)) {
2042      -                call_return_state_hooks_conditional(expr);
     2117 +        } else if (call_return_state_hooks_conditional(expr)) {
2043 2118                  return;
2044 2119          } else if (call_return_state_hooks_split_possible(expr)) {
2045 2120                  return;
2046 2121          } else if (split_positive_from_negative(expr)) {
2047 2122                  return;
2048 2123          } else if (call_return_state_hooks_split_null_non_null_zero(expr)) {
2049 2124                  return;
2050 2125          } else if (call_return_state_hooks_split_success_fail(expr)) {
2051 2126                  return;
2052 2127          } else if (splitable_function_call(expr)) {
↓ open down ↓ 432 lines elided ↑ open up ↑
2485 2560          if (!arg)
2486 2561                  return NULL;
2487 2562  
2488 2563          return get_variable_from_key(arg, key, sym);
2489 2564  }
2490 2565  
2491 2566  char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
2492 2567  {
2493 2568          char buf[256];
2494 2569          char *tmp;
2495      -        bool add_star = false;
     2570 +        int star_cnt = 0;
2496 2571  
2497 2572          if (!arg)
2498 2573                  return NULL;
2499 2574  
2500 2575          arg = strip_expr(arg);
2501 2576  
2502 2577          if (strcmp(key, "$") == 0)
2503 2578                  return expr_to_var_sym(arg, sym);
2504 2579  
2505 2580          if (strcmp(key, "*$") == 0) {
↓ open down ↓ 3 lines elided ↑ open up ↑
2509 2584                  } else {
2510 2585                          tmp = expr_to_var_sym(arg, sym);
2511 2586                          if (!tmp)
2512 2587                                  return NULL;
2513 2588                          snprintf(buf, sizeof(buf), "*%s", tmp);
2514 2589                          free_string(tmp);
2515 2590                          return alloc_string(buf);
2516 2591                  }
2517 2592          }
2518 2593  
2519      -        if (key[0] == '*') {
2520      -                add_star = true;
     2594 +        while (key[0] == '*') {
     2595 +                star_cnt++;
2521 2596                  key++;
2522 2597          }
2523 2598  
     2599 +        if (arg->type == EXPR_PREOP && arg->op == '&' && star_cnt) {
     2600 +                arg = strip_expr(arg->unop);
     2601 +                star_cnt--;
     2602 +        }
     2603 +
2524 2604          if (arg->type == EXPR_PREOP && arg->op == '&') {
2525 2605                  arg = strip_expr(arg->unop);
2526 2606                  tmp = expr_to_var_sym(arg, sym);
2527 2607                  if (!tmp)
2528 2608                          return NULL;
2529      -                snprintf(buf, sizeof(buf), "%s%s.%s",
2530      -                         add_star ? "*" : "", tmp, key + 3);
     2609 +                snprintf(buf, sizeof(buf), "%.*s%s.%s",
     2610 +                         star_cnt, "**********", tmp, key + 3);
2531 2611                  return alloc_string(buf);
2532 2612          }
2533 2613  
2534 2614          tmp = expr_to_var_sym(arg, sym);
2535 2615          if (!tmp)
2536 2616                  return NULL;
2537      -        snprintf(buf, sizeof(buf), "%s%s%s", add_star ? "*" : "", tmp, key + 1);
     2617 +        snprintf(buf, sizeof(buf), "%.*s%s%s", star_cnt, "**********", tmp, key + 1);
2538 2618          free_string(tmp);
2539 2619          return alloc_string(buf);
2540 2620  }
2541 2621  
2542 2622  char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
2543 2623  {
2544 2624          *vsl = NULL;
2545 2625  
2546 2626          if (strcmp("$", key) == 0)
2547 2627                  return expr_to_chunk_sym_vsl(arg, sym, vsl);
2548 2628          return get_variable_from_key(arg, key, sym);
2549 2629  }
2550 2630  
2551 2631  const char *state_name_to_param_name(const char *state_name, const char *param_name)
2552 2632  {
     2633 +        int star_cnt = 0;
2553 2634          int name_len;
2554      -        static char buf[256];
2555      -        bool add_star = false;
     2635 +        char buf[256];
2556 2636  
2557 2637          name_len = strlen(param_name);
2558 2638  
2559      -        if (state_name[0] == '*') {
2560      -                add_star = true;
     2639 +        while (state_name[0] == '*') {
     2640 +                star_cnt++;
2561 2641                  state_name++;
2562 2642          }
2563 2643  
     2644 +        /* ten out of ten stars! */
     2645 +        if (star_cnt > 10)
     2646 +                return NULL;
     2647 +
2564 2648          if (strcmp(state_name, param_name) == 0) {
2565      -                snprintf(buf, sizeof(buf), "%s$", add_star ? "*" : "");
     2649 +                snprintf(buf, sizeof(buf), "%.*s$", star_cnt, "**********");
2566 2650                  return alloc_sname(buf);
2567 2651          }
2568 2652  
2569 2653          if (state_name[name_len] == '-' && /* check for '-' from "->" */
2570 2654              strncmp(state_name, param_name, name_len) == 0) {
2571      -                snprintf(buf, sizeof(buf), "%s$%s",
2572      -                         add_star ? "*" : "", state_name + name_len);
     2655 +                snprintf(buf, sizeof(buf), "%.*s$%s", star_cnt, "**********", state_name + name_len);
2573 2656                  return alloc_sname(buf);
2574 2657          }
2575 2658          return NULL;
2576 2659  }
2577 2660  
2578 2661  const char *get_param_name_var_sym(const char *name, struct symbol *sym)
2579 2662  {
2580 2663          if (!sym || !sym->ident)
2581 2664                  return NULL;
2582 2665  
↓ open down ↓ 84 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX