Print this page
11506 smatch resync

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 ↓ 71 lines elided ↑ open up ↑
  72   72  static struct db_implies_cb_list *call_implies_cb_list;
  73   73  
  74   74  /* silently truncates if needed. */
  75   75  char *escape_newlines(const char *str)
  76   76  {
  77   77          char buf[1024] = "";
  78   78          bool found = false;
  79   79          int i, j;
  80   80  
  81   81          for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
  82      -                if (str[i] != '\n') {
       82 +                if (str[i] != '\r' && str[i] != '\n') {
  83   83                          buf[j] = str[i];
  84   84                          continue;
  85   85                  }
  86   86  
  87   87                  found = true;
  88   88                  buf[j++] = '\\';
  89   89                  if (j == sizeof(buf))
  90   90                           break;
  91   91                  buf[j] = 'n';
  92   92          }
↓ open down ↓ 152 lines elided ↑ open up ↑
 245  245                 "'%s', '%s', '%s', %%CALL_ID%%, %d, %d, %d, '%s', '%s');",
 246  246                 get_base_file(), get_function(), fn, is_static(call->fn),
 247  247                 type, param, key, value);
 248  248          sm_outfd = tmp_fd;
 249  249  
 250  250          free_string(fn);
 251  251  }
 252  252  
 253  253  void sql_insert_function_ptr(const char *fn, const char *struct_name)
 254  254  {
 255      -        sql_insert(function_ptr, "'%s', '%s', '%s', 0", get_base_file(), fn,
 256      -                   struct_name);
      255 +        sql_insert_or_ignore(function_ptr, "'%s', '%s', '%s', 0",
      256 +                             get_base_file(), fn, struct_name);
 257  257  }
 258  258  
 259  259  void sql_insert_return_implies(int type, int param, const char *key, const char *value)
 260  260  {
 261  261          sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 262  262                  get_base_file(), get_function(), (unsigned long)__inline_fn,
 263  263                  fn_static(), type, param, key, value);
 264  264  }
 265  265  
 266  266  void sql_insert_call_implies(int type, int param, const char *key, const char *value)
↓ open down ↓ 57 lines elided ↑ open up ↑
 324  324          sql_insert(data_info, "'%s', '%s', %d, '%s'",
 325  325                     (sym->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 326  326                     var, type, value);
 327  327  }
 328  328  
 329  329  void sql_save_constraint(const char *con)
 330  330  {
 331  331          if (!option_info)
 332  332                  return;
 333  333  
 334      -        sm_msg("SQL: insert or ignore into constraints (str) values('%s');", con);
      334 +        sm_msg("SQL: insert or ignore into constraints (str) values('%s');", escape_newlines(con));
 335  335  }
 336  336  
 337  337  void sql_save_constraint_required(const char *data, int op, const char *limit)
 338  338  {
 339  339          sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
 340  340  }
 341  341  
 342  342  void sql_copy_constraint_required(const char *new_limit, const char *old_limit)
 343  343  {
 344  344          if (!option_info)
↓ open down ↓ 20 lines elided ↑ open up ↑
 365  365                     !!(fn->symbol->ctype.modifiers & MOD_STATIC),
 366  366                     type, param, key, value);
 367  367  }
 368  368  
 369  369  void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name)
 370  370  {
 371  371          sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
 372  372                     tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
 373  373  }
 374  374  
 375      -void sql_insert_mtag_data(mtag_t tag, const char *var, int offset, int type, const char *value)
 376      -{
 377      -        sql_insert(mtag_data, "%lld, '%s', %d, %d, '%s'", tag, var, offset, type, value);
 378      -}
 379      -
 380  375  void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
 381  376  {
 382  377          sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
 383  378  }
 384  379  
 385  380  void sql_insert_mtag_alias(mtag_t orig, mtag_t alias)
 386  381  {
 387  382          sql_insert(mtag_alias, "%lld, %lld", orig, alias);
 388  383  }
 389  384  
↓ open down ↓ 353 lines elided ↑ open up ↑
 743  738  static char *show_offset(int offset)
 744  739  {
 745  740          static char buf[64];
 746  741  
 747  742          buf[0] = '\0';
 748  743          if (offset != -1)
 749  744                  snprintf(buf, sizeof(buf), "(-%d)", offset);
 750  745          return buf;
 751  746  }
 752  747  
      748 +int is_recursive_member(const char *name)
      749 +{
      750 +        char buf[256];
      751 +        const char *p, *next;
      752 +        int size;
      753 +
      754 +        p = strchr(name, '>');
      755 +        if (!p)
      756 +                return 0;
      757 +        p++;
      758 +        while (true) {
      759 +                next = strchr(p, '>');
      760 +                if (!next)
      761 +                        return 0;
      762 +                next++;
      763 +
      764 +                size = next - p;
      765 +                if (size >= sizeof(buf))
      766 +                        return 0;
      767 +                memcpy(buf, p, size);
      768 +                buf[size] = '\0';
      769 +                if (strstr(next, buf))
      770 +                        return 1;
      771 +                p = next;
      772 +        }
      773 +}
      774 +
 753  775  static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
 754  776          void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 755  777  {
 756  778          struct sm_state *sm;
      779 +        const char *sm_name;
 757  780          char *name;
 758  781          struct symbol *sym;
 759  782          int len;
 760  783          char printed_name[256];
 761  784          int is_address = 0;
      785 +        bool add_star;
 762  786          struct symbol *type;
 763  787  
 764  788          expr = strip_expr(expr);
 765  789          if (!expr)
 766  790                  return;
      791 +        type = get_type(expr);
      792 +        if (type && type_bits(type) < type_bits(&ulong_ctype))
      793 +                return;
      794 +
 767  795          if (expr->type == EXPR_PREOP && expr->op == '&') {
 768  796                  expr = strip_expr(expr->unop);
 769  797                  is_address = 1;
 770  798          }
 771  799  
 772      -        type = get_type(expr);
 773      -        if (type && type_bits(type) < type_bits(&ulong_ctype))
 774      -                return;
 775      -
 776  800          name = expr_to_var_sym(expr, &sym);
 777  801          if (!name || !sym)
 778  802                  goto free;
 779  803  
 780  804          len = strlen(name);
 781  805          FOR_EACH_SM(stree, sm) {
 782  806                  if (sm->sym != sym)
 783  807                          continue;
 784      -                if (strcmp(name, sm->name) == 0) {
      808 +                sm_name = sm->name;
      809 +                add_star = false;
      810 +                if (sm_name[0] == '*') {
      811 +                        add_star = true;
      812 +                        sm_name++;
      813 +                }
      814 +                // FIXME: simplify?
      815 +                if (!add_star && strcmp(name, sm_name) == 0) {
 785  816                          if (is_address)
 786  817                                  snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 787  818                          else /* these are already handled. fixme: handle them here */
 788  819                                  continue;
 789      -                } else if (sm->name[0] == '*' && strcmp(name, sm->name + 1) == 0) {
 790      -                        snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 791      -                } else if (strncmp(name, sm->name, len) == 0) {
 792      -                        if (isalnum(sm->name[len]))
      820 +                } else if (add_star && strcmp(name, sm_name) == 0) {
      821 +                        snprintf(printed_name, sizeof(printed_name), "%s*$%s",
      822 +                                 is_address ? "*" : "", show_offset(offset));
      823 +                } else if (strncmp(name, sm_name, len) == 0) {
      824 +                        if (sm_name[len] != '.' && sm_name[len] != '-')
 793  825                                  continue;
 794  826                          if (is_address)
 795      -                                snprintf(printed_name, sizeof(printed_name), "$%s->%s", show_offset(offset), sm->name + len + 1);
      827 +                                snprintf(printed_name, sizeof(printed_name),
      828 +                                         "%s$%s->%s", add_star ? "*" : "",
      829 +                                         show_offset(offset), sm_name + len + 1);
 796  830                          else
 797      -                                snprintf(printed_name, sizeof(printed_name), "$%s%s", show_offset(offset), sm->name + len);
      831 +                                snprintf(printed_name, sizeof(printed_name),
      832 +                                         "%s$%s%s", add_star ? "*" : "",
      833 +                                         show_offset(offset), sm_name + len);
 798  834                  } else {
 799  835                          continue;
 800  836                  }
      837 +                if (is_recursive_member(printed_name))
      838 +                        continue;
 801  839                  callback(call, param, printed_name, sm);
 802  840          } END_FOR_EACH_SM(sm);
 803  841  free:
 804  842          free_string(name);
 805  843  }
 806  844  
 807  845  static int param_used_callback(void *_container, int argc, char **argv, char **azColName)
 808  846  {
 809  847          char **container = _container;
 810  848          static char buf[256];
↓ open down ↓ 191 lines elided ↑ open up ↑
1002 1040  {
1003 1041          insert_string(&ptr_names, alloc_string(argv[0]));
1004 1042          return 0;
1005 1043  }
1006 1044  
1007 1045  static char *get_next_ptr_name(void)
1008 1046  {
1009 1047          char *ptr;
1010 1048  
1011 1049          FOR_EACH_PTR(ptr_names, ptr) {
1012      -                if (list_has_string(ptr_names_done, ptr))
     1050 +                if (!insert_string(&ptr_names_done, ptr))
1013 1051                          continue;
1014      -                insert_string(&ptr_names_done, ptr);
1015 1052                  return ptr;
1016 1053          } END_FOR_EACH_PTR(ptr);
1017 1054          return NULL;
1018 1055  }
1019 1056  
1020 1057  static void get_ptr_names(const char *file, const char *name)
1021 1058  {
1022 1059          char sql_filter[1024];
1023 1060          int before, after;
1024 1061  
↓ open down ↓ 192 lines elided ↑ open up ↑
1217 1254          };
1218 1255  
1219 1256          if (!sym || !sym->ident)
1220 1257                  return;
1221 1258  
1222 1259          info.sym = sym;
1223 1260          sql_select_implies("function, type, parameter, key, value", &info,
1224 1261                             call_implies_callbacks);
1225 1262  }
1226 1263  
1227      -static void print_initializer_list(struct expression_list *expr_list,
1228      -                struct symbol *struct_type)
     1264 +static char *get_return_compare_is_param(struct expression *expr)
1229 1265  {
1230      -        struct expression *expr;
1231      -        struct symbol *base_type;
1232      -        char struct_name[256];
     1266 +        char *var;
     1267 +        char buf[256];
     1268 +        int comparison;
     1269 +        int param;
1233 1270  
1234      -        FOR_EACH_PTR(expr_list, expr) {
1235      -                if (expr->type == EXPR_INDEX && expr->idx_expression && expr->idx_expression->type == EXPR_INITIALIZER) {
1236      -                        print_initializer_list(expr->idx_expression->expr_list, struct_type);
1237      -                        continue;
1238      -                }
1239      -                if (expr->type != EXPR_IDENTIFIER)
1240      -                        continue;
1241      -                if (!expr->expr_ident)
1242      -                        continue;
1243      -                if (!expr->ident_expression || !expr->ident_expression->symbol_name)
1244      -                        continue;
1245      -                base_type = get_type(expr->ident_expression);
1246      -                if (!base_type || base_type->type != SYM_FN)
1247      -                        continue;
1248      -                snprintf(struct_name, sizeof(struct_name), "(struct %s)->%s",
1249      -                         struct_type->ident->name, expr->expr_ident->name);
1250      -                sql_insert_function_ptr(expr->ident_expression->symbol_name->name,
1251      -                                        struct_name);
1252      -        } END_FOR_EACH_PTR(expr);
     1271 +        param = get_param_num(expr);
     1272 +        if (param < 0)
     1273 +                return NULL;
     1274 +
     1275 +        var = expr_to_var(expr);
     1276 +        if (!var)
     1277 +                return NULL;
     1278 +        snprintf(buf, sizeof(buf), "%s orig", var);
     1279 +        comparison = get_comparison_strings(var, buf);
     1280 +        free_string(var);
     1281 +
     1282 +        if (!comparison)
     1283 +                return NULL;
     1284 +
     1285 +        snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
     1286 +        return alloc_sname(buf);
1253 1287  }
1254 1288  
1255      -static void global_variable(struct symbol *sym)
     1289 +static char *get_return_compare_str(struct expression *expr)
1256 1290  {
1257      -        struct symbol *struct_type;
     1291 +        char *compare_str;
1258 1292  
1259      -        if (!sym->ident)
1260      -                return;
1261      -        if (!sym->initializer || sym->initializer->type != EXPR_INITIALIZER)
1262      -                return;
1263      -        struct_type = get_base_type(sym);
1264      -        if (!struct_type)
1265      -                return;
1266      -        if (struct_type->type == SYM_ARRAY) {
1267      -                struct_type = get_base_type(struct_type);
1268      -                if (!struct_type)
1269      -                        return;
     1293 +        compare_str = get_return_compare_is_param(expr);
     1294 +        if (compare_str)
     1295 +                return compare_str;
     1296 +
     1297 +        compare_str = expr_lte_to_param(expr, -1);
     1298 +        if (compare_str)
     1299 +                return compare_str;
     1300 +
     1301 +        return expr_param_comparison(expr, -1);
     1302 +}
     1303 +
     1304 +static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
     1305 +{
     1306 +        struct range_list *rl;
     1307 +        char *return_ranges;
     1308 +        sval_t sval;
     1309 +        char *compare_str;
     1310 +        char *math_str;
     1311 +        char buf[128];
     1312 +
     1313 +        *rl_p = NULL;
     1314 +
     1315 +        if (!expr)
     1316 +                return alloc_sname("");
     1317 +
     1318 +        if (get_implied_value(expr, &sval)) {
     1319 +                sval = sval_cast(cur_func_return_type(), sval);
     1320 +                *rl_p = alloc_rl(sval, sval);
     1321 +                return sval_to_str_or_err_ptr(sval);
1270 1322          }
1271      -        if (struct_type->type != SYM_STRUCT || !struct_type->ident)
1272      -                return;
1273      -        print_initializer_list(sym->initializer->expr_list, struct_type);
     1323 +
     1324 +        compare_str = expr_equal_to_param(expr, -1);
     1325 +        math_str = get_value_in_terms_of_parameter_math(expr);
     1326 +
     1327 +        if (get_implied_rl(expr, &rl) && !is_whole_rl(rl)) {
     1328 +                rl = cast_rl(cur_func_return_type(), rl);
     1329 +                return_ranges = show_rl(rl);
     1330 +        } else if (get_imaginary_absolute(expr, &rl)){
     1331 +                rl = cast_rl(cur_func_return_type(), rl);
     1332 +                return alloc_sname(show_rl(rl));
     1333 +        } else {
     1334 +                get_absolute_rl(expr, &rl);
     1335 +                rl = cast_rl(cur_func_return_type(), rl);
     1336 +                return_ranges = show_rl(rl);
     1337 +        }
     1338 +        *rl_p = rl;
     1339 +
     1340 +        if (compare_str) {
     1341 +                snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
     1342 +                return alloc_sname(buf);
     1343 +        }
     1344 +        if (math_str) {
     1345 +                snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
     1346 +                return alloc_sname(buf);
     1347 +        }
     1348 +        compare_str = get_return_compare_str(expr);
     1349 +        if (compare_str) {
     1350 +                snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
     1351 +                return alloc_sname(buf);
     1352 +        }
     1353 +
     1354 +        return return_ranges;
1274 1355  }
1275 1356  
1276 1357  static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
1277 1358  {
1278 1359          sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
1279 1360  }
1280 1361  
1281 1362  static void call_return_state_hooks_conditional(struct expression *expr)
1282 1363  {
1283 1364          struct returned_state_callback *cb;
1284 1365          struct range_list *rl;
1285      -        char *return_ranges;
     1366 +        const char *return_ranges;
1286 1367          int final_pass_orig = final_pass;
1287 1368  
1288 1369          __push_fake_cur_stree();
1289 1370  
1290 1371          final_pass = 0;
1291 1372          __split_whole_condition(expr->conditional);
1292 1373          final_pass = final_pass_orig;
1293 1374  
1294      -        if (get_implied_rl(expr->cond_true, &rl))
1295      -                rl = cast_rl(cur_func_return_type(), rl);
1296      -        else
1297      -                rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_true)));
1298      -        return_ranges = show_rl(rl);
     1375 +        return_ranges = get_return_ranges_str(expr->cond_true ?: expr->conditional, &rl);
     1376 +
1299 1377          set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1300 1378  
1301 1379          return_id++;
1302 1380          FOR_EACH_PTR(returned_state_callbacks, cb) {
1303      -                cb->callback(return_id, return_ranges, expr->cond_true);
     1381 +                cb->callback(return_id, (char *)return_ranges, expr->cond_true);
1304 1382          } END_FOR_EACH_PTR(cb);
1305 1383  
1306 1384          __push_true_states();
1307 1385          __use_false_states();
1308 1386  
1309      -        if (get_implied_rl(expr->cond_false, &rl))
1310      -                rl = cast_rl(cur_func_return_type(), rl);
1311      -        else
1312      -                rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_false)));
1313      -        return_ranges = show_rl(rl);
     1387 +        return_ranges = get_return_ranges_str(expr->cond_false, &rl);
1314 1388          set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1315 1389  
1316 1390          return_id++;
1317 1391          FOR_EACH_PTR(returned_state_callbacks, cb) {
1318      -                cb->callback(return_id, return_ranges, expr->cond_false);
     1392 +                cb->callback(return_id, (char *)return_ranges, expr->cond_false);
1319 1393          } END_FOR_EACH_PTR(cb);
1320 1394  
1321 1395          __merge_true_states();
1322 1396          __free_fake_cur_stree();
1323 1397  }
1324 1398  
1325 1399  static void call_return_state_hooks_compare(struct expression *expr)
1326 1400  {
1327 1401          struct returned_state_callback *cb;
1328 1402          char *return_ranges;
↓ open down ↓ 44 lines elided ↑ open up ↑
1373 1447          struct sm_state *tmp;
1374 1448  
1375 1449          FOR_EACH_PTR(slist, tmp) {
1376 1450                  if (strcmp(tmp->state->name, sm->state->name) == 0)
1377 1451                          return 1;
1378 1452          } END_FOR_EACH_PTR(tmp);
1379 1453  
1380 1454          return 0;
1381 1455  }
1382 1456  
1383      -static char *get_return_compare_str(struct expression *expr)
1384      -{
1385      -        char *compare_str;
1386      -        char *var;
1387      -        char buf[256];
1388      -        int comparison;
1389      -        int param;
1390      -
1391      -        compare_str = expr_lte_to_param(expr, -1);
1392      -        if (compare_str)
1393      -                return compare_str;
1394      -        param = get_param_num(expr);
1395      -        if (param < 0)
1396      -                return NULL;
1397      -
1398      -        var = expr_to_var(expr);
1399      -        if (!var)
1400      -                return NULL;
1401      -        snprintf(buf, sizeof(buf), "%s orig", var);
1402      -        comparison = get_comparison_strings(var, buf);
1403      -        free_string(var);
1404      -
1405      -        if (!comparison)
1406      -                return NULL;
1407      -
1408      -        snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
1409      -        return alloc_sname(buf);
1410      -}
1411      -
1412 1457  static int split_possible_helper(struct sm_state *sm, struct expression *expr)
1413 1458  {
1414 1459          struct returned_state_callback *cb;
1415 1460          struct range_list *rl;
1416 1461          char *return_ranges;
1417 1462          struct sm_state *tmp;
1418 1463          int ret = 0;
1419 1464          int nr_possible, nr_states;
1420      -        char *compare_str = NULL;
     1465 +        char *compare_str;
1421 1466          char buf[128];
1422 1467          struct state_list *already_handled = NULL;
     1468 +        sval_t sval;
1423 1469  
1424 1470          if (!sm || !sm->merged)
1425 1471                  return 0;
1426 1472  
1427 1473          if (too_many_possible(sm))
1428 1474                  return 0;
1429 1475  
1430 1476          /* bail if it gets too complicated */
1431      -        nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
     1477 +        nr_possible = 0;
     1478 +        FOR_EACH_PTR(sm->possible, tmp) {
     1479 +                if (tmp->merged)
     1480 +                        continue;
     1481 +                nr_possible++;
     1482 +        } END_FOR_EACH_PTR(tmp);
1432 1483          nr_states = get_db_state_count();
1433 1484          if (nr_states * nr_possible >= 2000)
1434 1485                  return 0;
1435 1486  
1436 1487          FOR_EACH_PTR(sm->possible, tmp) {
1437 1488                  if (tmp->merged)
1438 1489                          continue;
1439 1490                  if (ptr_in_list(tmp, already_handled))
1440 1491                          continue;
1441 1492                  add_ptr_list(&already_handled, tmp);
1442 1493  
1443 1494                  ret = 1;
1444 1495                  __push_fake_cur_stree();
1445 1496  
1446 1497                  overwrite_states_using_pool(sm, tmp);
1447 1498  
1448 1499                  rl = cast_rl(cur_func_return_type(), estate_rl(tmp->state));
1449 1500                  return_ranges = show_rl(rl);
1450 1501                  set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(clone_rl(rl)));
1451      -                compare_str = get_return_compare_str(expr);
1452      -                if (compare_str) {
1453      -                        snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1454      -                        return_ranges = alloc_sname(buf);
     1502 +                if (!rl_to_sval(rl, &sval)) {
     1503 +                        compare_str = get_return_compare_str(expr);
     1504 +                        if (compare_str) {
     1505 +                                snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
     1506 +                                return_ranges = alloc_sname(buf);
     1507 +                        }
1455 1508                  }
1456 1509  
1457 1510                  return_id++;
1458 1511                  FOR_EACH_PTR(returned_state_callbacks, cb) {
1459 1512                          cb->callback(return_id, return_ranges, expr);
1460 1513                  } END_FOR_EACH_PTR(cb);
1461 1514  
1462 1515                  __free_fake_cur_stree();
1463 1516          } END_FOR_EACH_PTR(tmp);
1464 1517  
↓ open down ↓ 6 lines elided ↑ open up ↑
1471 1524  {
1472 1525          struct sm_state *sm;
1473 1526  
1474 1527          if (!expr || expr_equal_to_param(expr, -1))
1475 1528                  return 0;
1476 1529  
1477 1530          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1478 1531          return split_possible_helper(sm, expr);
1479 1532  }
1480 1533  
1481      -static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
1482      -{
1483      -        struct range_list *rl;
1484      -        char *return_ranges;
1485      -        sval_t sval;
1486      -        char *compare_str;
1487      -        char *math_str;
1488      -        char buf[128];
1489      -
1490      -        *rl_p = NULL;
1491      -
1492      -        if (!expr)
1493      -                return alloc_sname("");
1494      -
1495      -        if (get_implied_value(expr, &sval)) {
1496      -                sval = sval_cast(cur_func_return_type(), sval);
1497      -                *rl_p = alloc_rl(sval, sval);
1498      -                return sval_to_str(sval);
1499      -        }
1500      -
1501      -        compare_str = expr_equal_to_param(expr, -1);
1502      -        math_str = get_value_in_terms_of_parameter_math(expr);
1503      -
1504      -        if (get_implied_rl(expr, &rl)) {
1505      -                rl = cast_rl(cur_func_return_type(), rl);
1506      -                return_ranges = show_rl(rl);
1507      -        } else if (get_imaginary_absolute(expr, &rl)){
1508      -                rl = cast_rl(cur_func_return_type(), rl);
1509      -                return alloc_sname(show_rl(rl));
1510      -        } else {
1511      -                rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr)));
1512      -                return_ranges = show_rl(rl);
1513      -        }
1514      -        *rl_p = rl;
1515      -
1516      -        if (compare_str) {
1517      -                snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1518      -                return alloc_sname(buf);
1519      -        }
1520      -        if (math_str) {
1521      -                snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
1522      -                return alloc_sname(buf);
1523      -        }
1524      -        compare_str = get_return_compare_str(expr);
1525      -        if (compare_str) {
1526      -                snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1527      -                return alloc_sname(buf);
1528      -        }
1529      -
1530      -        return return_ranges;
1531      -}
1532      -
1533 1534  static bool has_possible_negative(struct sm_state *sm)
1534 1535  {
1535 1536          struct sm_state *tmp;
1536 1537  
1537 1538          FOR_EACH_PTR(sm->possible, tmp) {
1538 1539                  if (!estate_rl(tmp->state))
1539 1540                          continue;
1540 1541                  if (sval_is_negative(estate_min(tmp->state)) &&
1541 1542                      sval_is_negative(estate_max(tmp->state)))
1542 1543                          return true;
↓ open down ↓ 18 lines elided ↑ open up ↑
1561 1562  }
1562 1563  
1563 1564  static int split_positive_from_negative(struct expression *expr)
1564 1565  {
1565 1566          struct sm_state *sm;
1566 1567          struct returned_state_callback *cb;
1567 1568          struct range_list *rl;
1568 1569          const char *return_ranges;
1569 1570          struct range_list *ret_rl;
1570 1571          int undo;
     1572 +        bool has_zero;
1571 1573  
1572 1574          /* We're going to print the states 3 times */
1573 1575          if (get_db_state_count() > 10000 / 3)
1574 1576                  return 0;
1575 1577  
1576 1578          if (!get_implied_rl(expr, &rl) || !rl)
1577 1579                  return 0;
1578 1580          if (is_whole_rl(rl) || is_whole_rl_non_zero(rl))
1579 1581                  return 0;
1580 1582          /* Forget about INT_MAX and larger */
1581 1583          if (rl_max(rl).value <= 0)
1582 1584                  return 0;
1583 1585          if (!sval_is_negative(rl_min(rl)))
1584 1586                  return 0;
1585 1587  
1586 1588          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1587 1589          if (!sm)
1588 1590                  return 0;
1589 1591          if (!has_possible_negative(sm))
1590 1592                  return 0;
     1593 +        has_zero = has_possible_zero_null(sm);
1591 1594  
1592      -        if (!assume(compare_expression(expr, '>', zero_expr())))
     1595 +        if (!assume(compare_expression(expr, has_zero ? '>' : SPECIAL_GTE, zero_expr())))
1593 1596                  return 0;
1594 1597  
1595 1598          return_id++;
1596 1599          return_ranges = get_return_ranges_str(expr, &ret_rl);
1597 1600          set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1598 1601          FOR_EACH_PTR(returned_state_callbacks, cb) {
1599 1602                  cb->callback(return_id, (char *)return_ranges, expr);
1600 1603          } END_FOR_EACH_PTR(cb);
1601 1604  
1602 1605          end_assume();
1603 1606  
1604      -        if (rl_has_sval(rl, sval_type_val(rl_type(rl), 0))) {
     1607 +        if (has_zero) {
1605 1608                  undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
1606 1609  
1607 1610                  return_id++;
1608 1611                  return_ranges = get_return_ranges_str(expr, &ret_rl);
1609 1612                  set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1610 1613                  FOR_EACH_PTR(returned_state_callbacks, cb) {
1611 1614                          cb->callback(return_id, (char *)return_ranges, expr);
1612 1615                  } END_FOR_EACH_PTR(cb);
1613 1616  
1614 1617                  if (undo)
↓ open down ↓ 8 lines elided ↑ open up ↑
1623 1626          FOR_EACH_PTR(returned_state_callbacks, cb) {
1624 1627                  cb->callback(return_id, (char *)return_ranges, expr);
1625 1628          } END_FOR_EACH_PTR(cb);
1626 1629  
1627 1630          if (undo)
1628 1631                  end_assume();
1629 1632  
1630 1633          return 1;
1631 1634  }
1632 1635  
1633      -static int call_return_state_hooks_split_null_non_null(struct expression *expr)
     1636 +static int call_return_state_hooks_split_null_non_null_zero(struct expression *expr)
1634 1637  {
1635 1638          struct returned_state_callback *cb;
1636 1639          struct range_list *rl;
1637 1640          struct range_list *nonnull_rl;
1638 1641          sval_t null_sval;
1639 1642          struct range_list *null_rl = NULL;
1640 1643          char *return_ranges;
1641 1644          struct sm_state *sm;
1642 1645          struct smatch_state *state;
1643 1646          int nr_states;
1644 1647          int final_pass_orig = final_pass;
1645 1648  
1646 1649          if (!expr || expr_equal_to_param(expr, -1))
1647 1650                  return 0;
1648 1651          if (expr->type == EXPR_CALL)
1649 1652                  return 0;
1650      -        if (!is_pointer(expr))
1651      -                return 0;
1652 1653  
1653 1654          sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1654 1655          if (!sm)
1655 1656                  return 0;
1656 1657          if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1657 1658                  return 0;
1658 1659          state = sm->state;
1659 1660          if (!estate_rl(state))
1660 1661                  return 0;
1661 1662          if (estate_min(state).value == 0 && estate_max(state).value == 0)
↓ open down ↓ 323 lines elided ↑ open up ↑
1985 1986          if (expr && (expr->type == EXPR_COMPARE ||
1986 1987                       !get_implied_value(expr, &sval)) &&
1987 1988              (is_condition(expr) || is_boolean(expr))) {
1988 1989                  call_return_state_hooks_compare(expr);
1989 1990                  return;
1990 1991          } else if (is_conditional(expr)) {
1991 1992                  call_return_state_hooks_conditional(expr);
1992 1993                  return;
1993 1994          } else if (call_return_state_hooks_split_possible(expr)) {
1994 1995                  return;
1995      -        } else if (call_return_state_hooks_split_null_non_null(expr)) {
     1996 +        } else if (split_positive_from_negative(expr)) {
1996 1997                  return;
     1998 +        } else if (call_return_state_hooks_split_null_non_null_zero(expr)) {
     1999 +                return;
1997 2000          } else if (call_return_state_hooks_split_success_fail(expr)) {
1998 2001                  return;
1999 2002          } else if (splitable_function_call(expr)) {
2000 2003                  return;
2001      -        } else if (split_positive_from_negative(expr)) {
2002      -                return;
2003 2004          } else if (split_by_bool_param(expr)) {
2004 2005          } else if (split_by_null_nonnull_param(expr)) {
2005 2006                  return;
2006 2007          }
2007 2008  
2008 2009  vanilla:
2009 2010          return_ranges = get_return_ranges_str(expr, &ret_rl);
2010 2011          set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
2011 2012  
2012 2013          return_id++;
↓ open down ↓ 188 lines elided ↑ open up ↑
2201 2202          char tmp[256];
2202 2203          char *p = buf;
2203 2204          char *table = _table;
2204 2205          int i;
2205 2206  
2206 2207  
2207 2208          p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
2208 2209          for (i = 0; i < argc; i++) {
2209 2210                  if (i)
2210 2211                          p += snprintf(p, 4096 - (p - buf), ", ");
2211      -                sqlite3_snprintf(sizeof(tmp), tmp, "%q", argv[i]);
     2212 +                sqlite3_snprintf(sizeof(tmp), tmp, "%q", escape_newlines(argv[i]));
2212 2213                  p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
2213 2214  
2214 2215          }
2215 2216          p += snprintf(p, 4096 - (p - buf), ");");
2216 2217          if (p - buf > 4096)
2217 2218                  return 0;
2218 2219  
2219 2220          sm_msg("SQL: %s", buf);
2220 2221          return 0;
2221 2222  }
↓ open down ↓ 132 lines elided ↑ open up ↑
2354 2355  
2355 2356                  replace_table[i++] = func;
2356 2357                  replace_table[i++] = orig;
2357 2358                  replace_table[i++] = new;
2358 2359          }
2359 2360  }
2360 2361  
2361 2362  void register_definition_db_callbacks(int id)
2362 2363  {
2363 2364          add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2364      -        add_hook(&global_variable, BASE_HOOK);
2365      -        add_hook(&global_variable, DECLARATION_HOOK);
2366 2365          add_split_return_callback(match_return_info);
2367 2366          add_split_return_callback(print_returned_struct_members);
2368 2367          add_hook(&call_return_state_hooks, RETURN_HOOK);
2369 2368          add_hook(&match_end_func_info, END_FUNC_HOOK);
2370 2369          add_hook(&match_after_func, AFTER_FUNC_HOOK);
2371 2370  
2372 2371          add_hook(&match_data_from_db, FUNC_DEF_HOOK);
2373 2372          add_hook(&match_call_implies, FUNC_DEF_HOOK);
2374 2373          add_hook(&match_return_implies, CALL_HOOK_AFTER_INLINE);
2375 2374  
↓ open down ↓ 14 lines elided ↑ open up ↑
2390 2389          char *name = NULL;
2391 2390          char member_name[256];
2392 2391  
2393 2392          *sym = NULL;
2394 2393  
2395 2394          if (param == -1) {
2396 2395                  const char *star = "";
2397 2396  
2398 2397                  if (expr->type != EXPR_ASSIGNMENT)
2399 2398                          return NULL;
     2399 +                if (get_type(expr->left) == &int_ctype && strcmp(key, "$") != 0)
     2400 +                        return NULL;
2400 2401                  name = expr_to_var_sym(expr->left, sym);
2401 2402                  if (!name)
2402 2403                          return NULL;
2403 2404                  if (key[0] == '*') {
2404 2405                          star = "*";
2405 2406                          key++;
2406 2407                  }
2407 2408                  if (strncmp(key, "$", 1) != 0)
2408 2409                          return name;
2409 2410                  snprintf(member_name, sizeof(member_name), "%s%s%s", star, name, key + 1);
↓ open down ↓ 10 lines elided ↑ open up ↑
2420 2421          if (!arg)
2421 2422                  return NULL;
2422 2423  
2423 2424          return get_variable_from_key(arg, key, sym);
2424 2425  }
2425 2426  
2426 2427  char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
2427 2428  {
2428 2429          char buf[256];
2429 2430          char *tmp;
     2431 +        bool add_star = false;
2430 2432  
2431 2433          if (!arg)
2432 2434                  return NULL;
2433 2435  
2434 2436          arg = strip_expr(arg);
2435 2437  
2436 2438          if (strcmp(key, "$") == 0)
2437 2439                  return expr_to_var_sym(arg, sym);
2438 2440  
2439 2441          if (strcmp(key, "*$") == 0) {
↓ open down ↓ 3 lines elided ↑ open up ↑
2443 2445                  } else {
2444 2446                          tmp = expr_to_var_sym(arg, sym);
2445 2447                          if (!tmp)
2446 2448                                  return NULL;
2447 2449                          snprintf(buf, sizeof(buf), "*%s", tmp);
2448 2450                          free_string(tmp);
2449 2451                          return alloc_string(buf);
2450 2452                  }
2451 2453          }
2452 2454  
     2455 +        if (key[0] == '*') {
     2456 +                add_star = true;
     2457 +                key++;
     2458 +        }
     2459 +
2453 2460          if (arg->type == EXPR_PREOP && arg->op == '&') {
2454 2461                  arg = strip_expr(arg->unop);
2455 2462                  tmp = expr_to_var_sym(arg, sym);
2456 2463                  if (!tmp)
2457 2464                          return NULL;
2458      -                snprintf(buf, sizeof(buf), "%s.%s", tmp, key + 3);
     2465 +                snprintf(buf, sizeof(buf), "%s%s.%s",
     2466 +                         add_star ? "*" : "", tmp, key + 3);
2459 2467                  return alloc_string(buf);
2460 2468          }
2461 2469  
2462 2470          tmp = expr_to_var_sym(arg, sym);
2463 2471          if (!tmp)
2464 2472                  return NULL;
2465      -        snprintf(buf, sizeof(buf), "%s%s", tmp, key + 1);
     2473 +        snprintf(buf, sizeof(buf), "%s%s%s", add_star ? "*" : "", tmp, key + 1);
2466 2474          free_string(tmp);
2467 2475          return alloc_string(buf);
2468 2476  }
2469 2477  
2470 2478  char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
2471 2479  {
2472 2480          *vsl = NULL;
2473 2481  
2474 2482          if (strcmp("$", key) == 0)
2475 2483                  return expr_to_chunk_sym_vsl(arg, sym, vsl);
2476 2484          return get_variable_from_key(arg, key, sym);
2477 2485  }
2478 2486  
2479 2487  const char *state_name_to_param_name(const char *state_name, const char *param_name)
2480 2488  {
2481 2489          int name_len;
2482 2490          static char buf[256];
     2491 +        bool add_star = false;
2483 2492  
2484 2493          name_len = strlen(param_name);
2485 2494  
     2495 +        if (state_name[0] == '*') {
     2496 +                add_star = true;
     2497 +                state_name++;
     2498 +        }
     2499 +
2486 2500          if (strcmp(state_name, param_name) == 0) {
2487      -                return "$";
2488      -        } else if (state_name[name_len] == '-' && /* check for '-' from "->" */
     2501 +                snprintf(buf, sizeof(buf), "%s$", add_star ? "*" : "");
     2502 +                return buf;
     2503 +        }
     2504 +
     2505 +        if (state_name[name_len] == '-' && /* check for '-' from "->" */
2489 2506              strncmp(state_name, param_name, name_len) == 0) {
2490      -                snprintf(buf, sizeof(buf), "$%s", state_name + name_len);
     2507 +                snprintf(buf, sizeof(buf), "%s$%s",
     2508 +                         add_star ? "*" : "", state_name + name_len);
2491 2509                  return buf;
2492      -        } else if (state_name[0] == '*' && strcmp(state_name + 1, param_name) == 0) {
2493      -                return "*$";
2494 2510          }
2495 2511          return NULL;
2496 2512  }
2497 2513  
2498 2514  const char *get_param_name_var_sym(const char *name, struct symbol *sym)
2499 2515  {
2500 2516          if (!sym || !sym->ident)
2501 2517                  return NULL;
2502 2518  
2503 2519          return state_name_to_param_name(name, sym->ident->name);
↓ open down ↓ 83 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX