11506 smatch resync

   1 /*
   2  * Copyright (C) 2006,2008 Dan Carpenter.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  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 #define _GNU_SOURCE 1
  19 #include <unistd.h>
  20 #include <stdio.h>
  21 #include "token.h"
  22 #include "scope.h"
  23 #include "smatch.h"
  24 #include "smatch_expression_stacks.h"
  25 #include "smatch_extra.h"
  26 #include "smatch_slist.h"
  27 
  28 int __in_fake_assign;
  29 int __in_fake_struct_assign;
  30 int in_fake_env;
  31 int final_pass;
  32 int __inline_call;
  33 struct expression  *__inline_fn;
  34 
  35 static int __smatch_lineno = 0;
  36 
  37 static char *base_file;
  38 static const char *filename;
  39 static char *pathname;
  40 static char *full_filename;
  41 static char *full_base_file;
  42 static char *cur_func;
  43 static unsigned int loop_count;
  44 static int last_goto_statement_handled;
  45 int __expr_stmt_count;
  46 int __in_function_def;
  47 static struct expression_list *switch_expr_stack = NULL;
  48 static struct expression_list *post_op_stack = NULL;
  49 
  50 static struct ptr_list *backup;
  51 
  52 struct expression_list *big_expression_stack;
  53 struct statement_list *big_statement_stack;
  54 struct statement *__prev_stmt;
  55 struct statement *__cur_stmt;
  56 struct statement *__next_stmt;
  57 int __in_pre_condition = 0;
  58 int __bail_on_rest_of_function = 0;
  59 static struct timeval fn_start_time;
  60 static struct timeval outer_fn_start_time;
  61 char *get_function(void) { return cur_func; }
  62 int get_lineno(void) { return __smatch_lineno; }
  63 int inside_loop(void) { return !!loop_count; }
  64 int definitely_inside_loop(void) { return !!(loop_count & ~0x08000000); }
  65 struct expression *get_switch_expr(void) { return top_expression(switch_expr_stack); }
  66 int in_expression_statement(void) { return !!__expr_stmt_count; }
  67 
  68 static void split_symlist(struct symbol_list *sym_list);
  69 static void split_declaration(struct symbol_list *sym_list);
  70 static void split_expr_list(struct expression_list *expr_list, struct expression *parent);
  71 static void add_inline_function(struct symbol *sym);
  72 static void parse_inline(struct expression *expr);
  73 
  74 int option_assume_loops = 0;
  75 int option_two_passes = 0;
  76 struct symbol *cur_func_sym = NULL;
  77 struct stree *global_states;
  78 
  79 long long valid_ptr_min = 4096;
  80 long long valid_ptr_max = 2117777777;
  81 sval_t valid_ptr_min_sval = {
  82         .type = &ptr_ctype,
  83         {.value = 4096},
  84 };
  85 sval_t valid_ptr_max_sval = {
  86         .type = &ptr_ctype,
  87         {.value = LONG_MAX - 100000},
  88 };
  89 struct range_list *valid_ptr_rl;
  90 
  91 static void set_valid_ptr_max(void)
  92 {
  93         if (type_bits(&ptr_ctype) == 32)
  94                 valid_ptr_max = 2117777777;
  95         else if (type_bits(&ptr_ctype) == 64)
  96                 valid_ptr_max = 2117777777777777777LL;
  97 
  98         valid_ptr_max_sval.value = valid_ptr_max;
  99 }
 100 
 101 static void alloc_valid_ptr_rl(void)
 102 {
 103         valid_ptr_rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
 104         valid_ptr_rl = cast_rl(&ptr_ctype, valid_ptr_rl);
 105         valid_ptr_rl = clone_rl_permanent(valid_ptr_rl);
 106 }
 107 
 108 int outside_of_function(void)
 109 {
 110         return cur_func_sym == NULL;
 111 }
 112 
 113 const char *get_filename(void)
 114 {
 115         if (option_info && option_full_path)
 116                 return full_base_file;
 117         if (option_info)
 118                 return base_file;
 119         if (option_full_path)
 120                 return full_filename;
 121         return filename;
 122 }
 123 
 124 const char *get_base_file(void)
 125 {
 126         if (option_full_path)
 127                 return full_base_file;
 128         return base_file;
 129 }
 130 
 131 static void set_position(struct position pos)
 132 {
 133         int len;
 134         static int prev_stream = -1;
 135 
 136         if (in_fake_env)
 137                 return;
 138 
 139         if (pos.stream == 0 && pos.line == 0)
 140                 return;
 141 
 142         __smatch_lineno = pos.line;
 143 
 144         if (pos.stream == prev_stream)
 145                 return;
 146 
 147         filename = stream_name(pos.stream);
 148 
 149         free(full_filename);
 150         pathname = getcwd(NULL, 0);
 151         if (pathname) {
 152                 len = strlen(pathname) + 1 + strlen(filename) + 1;
 153                 full_filename = malloc(len);
 154                 snprintf(full_filename, len, "%s/%s", pathname, filename);
 155         } else {
 156                 full_filename = alloc_string(filename);
 157         }
 158         free(pathname);
 159 }
 160 
 161 int is_assigned_call(struct expression *expr)
 162 {
 163         struct expression *parent = expr_get_parent_expr(expr);
 164 
 165         if (parent &&
 166             parent->type == EXPR_ASSIGNMENT &&
 167             parent->op == '=' &&
 168             strip_expr(parent->right) == expr)
 169                 return 1;
 170 
 171         return 0;
 172 }
 173 
 174 static int is_inline_func(struct expression *expr)
 175 {
 176         if (expr->type != EXPR_SYMBOL || !expr->symbol)
 177                 return 0;
 178         if (expr->symbol->ctype.modifiers & MOD_INLINE)
 179                 return 1;
 180         return 0;
 181 }
 182 
 183 static int is_noreturn_func(struct expression *expr)
 184 {
 185         if (expr->type != EXPR_SYMBOL || !expr->symbol)
 186                 return 0;
 187         if (expr->symbol->ctype.modifiers & MOD_NORETURN)
 188                 return 1;
 189         return 0;
 190 }
 191 
 192 static int inline_budget = 20;
 193 
 194 int inlinable(struct expression *expr)
 195 {
 196         struct symbol *sym;
 197         struct statement *last_stmt = NULL;
 198 
 199         if (__inline_fn)  /* don't nest */
 200                 return 0;
 201 
 202         if (expr->type != EXPR_SYMBOL || !expr->symbol)
 203                 return 0;
 204         if (is_no_inline_function(expr->symbol->ident->name))
 205                 return 0;
 206         sym = get_base_type(expr->symbol);
 207         if (sym->stmt && sym->stmt->type == STMT_COMPOUND) {
 208                 if (ptr_list_size((struct ptr_list *)sym->stmt->stmts) > 10)
 209                         return 0;
 210                 if (sym->stmt->type != STMT_COMPOUND)
 211                         return 0;
 212                 last_stmt = last_ptr_list((struct ptr_list *)sym->stmt->stmts);
 213         }
 214         if (sym->inline_stmt && sym->inline_stmt->type == STMT_COMPOUND) {
 215                 if (ptr_list_size((struct ptr_list *)sym->inline_stmt->stmts) > 10)
 216                         return 0;
 217                 if (sym->inline_stmt->type != STMT_COMPOUND)
 218                         return 0;
 219                 last_stmt = last_ptr_list((struct ptr_list *)sym->inline_stmt->stmts);
 220         }
 221 
 222         if (!last_stmt)
 223                 return 0;
 224 
 225         /* the magic numbers in this function are pulled out of my bum. */
 226         if (last_stmt->pos.line > sym->pos.line + inline_budget)
 227                 return 0;
 228 
 229         return 1;
 230 }
 231 
 232 void __process_post_op_stack(void)
 233 {
 234         struct expression *expr;
 235 
 236         FOR_EACH_PTR(post_op_stack, expr) {
 237                 __pass_to_client(expr, OP_HOOK);
 238         } END_FOR_EACH_PTR(expr);
 239 
 240         __free_ptr_list((struct ptr_list **)&post_op_stack);
 241 }
 242 
 243 static int handle_comma_assigns(struct expression *expr)
 244 {
 245         struct expression *right;
 246         struct expression *assign;
 247 
 248         right = strip_expr(expr->right);
 249         if (right->type != EXPR_COMMA)
 250                 return 0;
 251 
 252         __split_expr(right->left);
 253         __process_post_op_stack();
 254 
 255         assign = assign_expression(expr->left, '=', right->right);
 256         __split_expr(assign);
 257 
 258         return 1;
 259 }
 260 
 261 /* This is to handle *p++ = foo; assignments */
 262 static int handle_postop_assigns(struct expression *expr)
 263 {
 264         struct expression *left, *fake_left;
 265         struct expression *assign;
 266 
 267         left = strip_expr(expr->left);
 268         if (left->type != EXPR_PREOP || left->op != '*')
 269                 return 0;
 270         left = strip_expr(left->unop);
 271         if (left->type != EXPR_POSTOP)
 272                 return 0;
 273 
 274         fake_left = deref_expression(strip_expr(left->unop));
 275         assign = assign_expression(fake_left, '=', expr->right);
 276 
 277         __split_expr(assign);
 278         __split_expr(expr->left);
 279 
 280         return 1;
 281 }
 282 
 283 static int prev_expression_is_getting_address(struct expression *expr)
 284 {
 285         struct expression *parent;
 286 
 287         do {
 288                 parent = expr_get_parent_expr(expr);
 289 
 290                 if (!parent)
 291                         return 0;
 292                 if (parent->type == EXPR_PREOP && parent->op == '&')
 293                         return 1;
 294                 if (parent->type == EXPR_PREOP && parent->op == '(')
 295                         goto next;
 296                 if (parent->type == EXPR_DEREF && parent->op == '.')
 297                         goto next;
 298 
 299                 return 0;
 300 next:
 301                 expr = parent;
 302         } while (1);
 303 }
 304 
 305 static void handle_builtin_overflow_func(struct expression *expr)
 306 {
 307         struct expression *a, *b, *res, *assign;
 308         int op;
 309 
 310         if (sym_name_is("__builtin_add_overflow", expr->fn))
 311                 op = '+';
 312         else if (sym_name_is("__builtin_sub_overflow", expr->fn))
 313                 op = '-';
 314         else if (sym_name_is("__builtin_mul_overflow", expr->fn))
 315                 op = '*';
 316         else
 317                 return;
 318 
 319         a = get_argument_from_call_expr(expr->args, 0);
 320         b = get_argument_from_call_expr(expr->args, 1);
 321         res = get_argument_from_call_expr(expr->args, 2);
 322 
 323         assign = assign_expression(deref_expression(res), '=', binop_expression(a, op, b));
 324         __split_expr(assign);
 325 }
 326 
 327 static int handle__builtin_choose_expr(struct expression *expr)
 328 {
 329         struct expression *const_expr, *expr1, *expr2;
 330         sval_t sval;
 331 
 332         if (!sym_name_is("__builtin_choose_expr", expr->fn))
 333                 return 0;
 334 
 335         const_expr = get_argument_from_call_expr(expr->args, 0);
 336         expr1 = get_argument_from_call_expr(expr->args, 1);
 337         expr2 = get_argument_from_call_expr(expr->args, 2);
 338 
 339         if (!get_value(const_expr, &sval) || !expr1 || !expr2)
 340                 return 0;
 341         if (sval.value)
 342                 __split_expr(expr1);
 343         else
 344                 __split_expr(expr2);
 345         return 1;
 346 }
 347 
 348 static int handle__builtin_choose_expr_assigns(struct expression *expr)
 349 {
 350         struct expression *const_expr, *right, *expr1, *expr2, *fake;
 351         sval_t sval;
 352 
 353         right = strip_expr(expr->right);
 354         if (right->type != EXPR_CALL)
 355                 return 0;
 356         if (!sym_name_is("__builtin_choose_expr", right->fn))
 357                 return 0;
 358 
 359         const_expr = get_argument_from_call_expr(right->args, 0);
 360         expr1 = get_argument_from_call_expr(right->args, 1);
 361         expr2 = get_argument_from_call_expr(right->args, 2);
 362 
 363         if (!get_value(const_expr, &sval) || !expr1 || !expr2)
 364                 return 0;
 365 
 366         fake = assign_expression(expr->left, '=', sval.value ? expr1 : expr2);
 367         __split_expr(fake);
 368         return 1;
 369 }
 370 
 371 void __split_expr(struct expression *expr)
 372 {
 373         if (!expr)
 374                 return;
 375 
 376         // sm_msg(" Debug expr_type %d %s", expr->type, show_special(expr->op));
 377 
 378         if (__in_fake_assign && expr->type != EXPR_ASSIGNMENT)
 379                 return;
 380         if (__in_fake_assign >= 4)  /* don't allow too much nesting */
 381                 return;
 382 
 383         push_expression(&big_expression_stack, expr);
 384         set_position(expr->pos);
 385         __pass_to_client(expr, EXPR_HOOK);
 386 
 387         switch (expr->type) {
 388         case EXPR_PREOP:
 389                 expr_set_parent_expr(expr->unop, expr);
 390 
 391                 if (expr->op == '*' &&
 392                     !prev_expression_is_getting_address(expr))
 393                         __pass_to_client(expr, DEREF_HOOK);
 394                 __split_expr(expr->unop);
 395                 __pass_to_client(expr, OP_HOOK);
 396                 break;
 397         case EXPR_POSTOP:
 398                 expr_set_parent_expr(expr->unop, expr);
 399 
 400                 __split_expr(expr->unop);
 401                 push_expression(&post_op_stack, expr);
 402                 break;
 403         case EXPR_STATEMENT:
 404                 __expr_stmt_count++;
 405                 if (expr->statement && !expr->statement) {
 406                         stmt_set_parent_stmt(expr->statement,
 407                                         last_ptr_list((struct ptr_list *)big_statement_stack));
 408                 }
 409                 __split_stmt(expr->statement);
 410                 __expr_stmt_count--;
 411                 break;
 412         case EXPR_LOGICAL:
 413         case EXPR_COMPARE:
 414                 expr_set_parent_expr(expr->left, expr);
 415                 expr_set_parent_expr(expr->right, expr);
 416 
 417                 __pass_to_client(expr, LOGIC_HOOK);
 418                 __handle_logic(expr);
 419                 break;
 420         case EXPR_BINOP:
 421                 expr_set_parent_expr(expr->left, expr);
 422                 expr_set_parent_expr(expr->right, expr);
 423 
 424                 __pass_to_client(expr, BINOP_HOOK);
 425         case EXPR_COMMA:
 426                 expr_set_parent_expr(expr->left, expr);
 427                 expr_set_parent_expr(expr->right, expr);
 428 
 429                 __split_expr(expr->left);
 430                 __process_post_op_stack();
 431                 __split_expr(expr->right);
 432                 break;
 433         case EXPR_ASSIGNMENT: {
 434                 struct expression *right;
 435 
 436                 expr_set_parent_expr(expr->left, expr);
 437                 expr_set_parent_expr(expr->right, expr);
 438 
 439                 right = strip_expr(expr->right);
 440                 if (!right)
 441                         break;
 442 
 443                 __pass_to_client(expr, RAW_ASSIGNMENT_HOOK);
 444 
 445                 /* foo = !bar() */
 446                 if (__handle_condition_assigns(expr))
 447                         break;
 448                 /* foo = (x < 5 ? foo : 5); */
 449                 if (__handle_select_assigns(expr))
 450                         break;
 451                 /* foo = ({frob(); frob(); frob(); 1;}) */
 452                 if (__handle_expr_statement_assigns(expr))
 453                         break;
 454                 /* foo = (3, 4); */
 455                 if (handle_comma_assigns(expr))
 456                         break;
 457                 if (handle_postop_assigns(expr))
 458                         break;
 459                 if (handle__builtin_choose_expr_assigns(expr))
 460                         break;
 461 
 462                 __split_expr(expr->right);
 463                 if (outside_of_function())
 464                         __pass_to_client(expr, GLOBAL_ASSIGNMENT_HOOK);
 465                 else
 466                         __pass_to_client(expr, ASSIGNMENT_HOOK);
 467 
 468                 __fake_struct_member_assignments(expr);
 469 
 470                 if (expr->op == '=' && right->type == EXPR_CALL)
 471                         __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
 472 
 473                 if (get_macro_name(right->pos) &&
 474                     get_macro_name(expr->pos) != get_macro_name(right->pos))
 475                         __pass_to_client(expr, MACRO_ASSIGNMENT_HOOK);
 476 
 477                 __pass_to_client(expr, ASSIGNMENT_HOOK_AFTER);
 478 
 479                 __split_expr(expr->left);
 480                 break;
 481         }
 482         case EXPR_DEREF:
 483                 expr_set_parent_expr(expr->deref, expr);
 484 
 485                 __pass_to_client(expr, DEREF_HOOK);
 486                 __split_expr(expr->deref);
 487                 break;
 488         case EXPR_SLICE:
 489                 expr_set_parent_expr(expr->base, expr);
 490 
 491                 __split_expr(expr->base);
 492                 break;
 493         case EXPR_CAST:
 494         case EXPR_FORCE_CAST:
 495                 expr_set_parent_expr(expr->cast_expression, expr);
 496 
 497                 __pass_to_client(expr, CAST_HOOK);
 498                 __split_expr(expr->cast_expression);
 499                 break;
 500         case EXPR_SIZEOF:
 501                 if (expr->cast_expression)
 502                         __pass_to_client(strip_parens(expr->cast_expression),
 503                                          SIZEOF_HOOK);
 504                 break;
 505         case EXPR_OFFSETOF:
 506         case EXPR_ALIGNOF:
 507                 evaluate_expression(expr);
 508                 break;
 509         case EXPR_CONDITIONAL:
 510         case EXPR_SELECT:
 511                 expr_set_parent_expr(expr->conditional, expr);
 512                 expr_set_parent_expr(expr->cond_true, expr);
 513                 expr_set_parent_expr(expr->cond_false, expr);
 514 
 515                 if (known_condition_true(expr->conditional)) {
 516                         __split_expr(expr->cond_true);
 517                         break;
 518                 }
 519                 if (known_condition_false(expr->conditional)) {
 520                         __split_expr(expr->cond_false);
 521                         break;
 522                 }
 523                 __pass_to_client(expr, SELECT_HOOK);
 524                 __split_whole_condition(expr->conditional);
 525                 __split_expr(expr->cond_true);
 526                 __push_true_states();
 527                 __use_false_states();
 528                 __split_expr(expr->cond_false);
 529                 __merge_true_states();
 530                 break;
 531         case EXPR_CALL:
 532                 expr_set_parent_expr(expr->fn, expr);
 533 
 534                 if (sym_name_is("__builtin_constant_p", expr->fn))
 535                         break;
 536                 if (handle__builtin_choose_expr(expr))
 537                         break;
 538                 split_expr_list(expr->args, expr);
 539                 __split_expr(expr->fn);
 540                 if (is_inline_func(expr->fn))
 541                         add_inline_function(expr->fn->symbol);
 542                 if (inlinable(expr->fn))
 543                         __inline_call = 1;
 544                 __process_post_op_stack();
 545                 __pass_to_client(expr, FUNCTION_CALL_HOOK_BEFORE);
 546                 __pass_to_client(expr, FUNCTION_CALL_HOOK);
 547                 __inline_call = 0;
 548                 if (inlinable(expr->fn)) {
 549                         parse_inline(expr);
 550                 }
 551                 __pass_to_client(expr, CALL_HOOK_AFTER_INLINE);
 552                 if (is_noreturn_func(expr->fn))
 553                         nullify_path();
 554                 handle_builtin_overflow_func(expr);
 555                 break;
 556         case EXPR_INITIALIZER:
 557                 split_expr_list(expr->expr_list, expr);
 558                 break;
 559         case EXPR_IDENTIFIER:
 560                 expr_set_parent_expr(expr->ident_expression, expr);
 561                 __split_expr(expr->ident_expression);
 562                 break;
 563         case EXPR_INDEX:
 564                 expr_set_parent_expr(expr->idx_expression, expr);
 565                 __split_expr(expr->idx_expression);
 566                 break;
 567         case EXPR_POS:
 568                 expr_set_parent_expr(expr->init_expr, expr);
 569                 __split_expr(expr->init_expr);
 570                 break;
 571         case EXPR_SYMBOL:
 572                 __pass_to_client(expr, SYM_HOOK);
 573                 break;
 574         case EXPR_STRING:
 575                 __pass_to_client(expr, STRING_HOOK);
 576                 break;
 577         default:
 578                 break;
 579         };
 580         pop_expression(&big_expression_stack);
 581 }
 582 
 583 static int is_forever_loop(struct statement *stmt)
 584 {
 585         struct expression *expr;
 586         sval_t sval;
 587 
 588         expr = strip_expr(stmt->iterator_pre_condition);
 589         if (!expr)
 590                 expr = stmt->iterator_post_condition;
 591         if (!expr) {
 592                 /* this is a for(;;) loop... */
 593                 return 1;
 594         }
 595 
 596         if (get_value(expr, &sval) && sval.value != 0)
 597                 return 1;
 598 
 599         return 0;
 600 }
 601 
 602 static int loop_num;
 603 static char *get_loop_name(int num)
 604 {
 605         char buf[256];
 606 
 607         snprintf(buf, 255, "-loop%d", num);
 608         buf[255] = '\0';
 609         return alloc_sname(buf);
 610 }
 611 
 612 /*
 613  * Pre Loops are while and for loops.
 614  */
 615 static void handle_pre_loop(struct statement *stmt)
 616 {
 617         int once_through; /* we go through the loop at least once */
 618         struct sm_state *extra_sm = NULL;
 619         int unchanged = 0;
 620         char *loop_name;
 621         struct stree *stree = NULL;
 622         struct sm_state *sm = NULL;
 623 
 624         loop_name = get_loop_name(loop_num);
 625         loop_num++;
 626 
 627         __split_stmt(stmt->iterator_pre_statement);
 628         __prev_stmt = stmt->iterator_pre_statement;
 629 
 630         once_through = implied_condition_true(stmt->iterator_pre_condition);
 631 
 632         loop_count++;
 633         __push_continues();
 634         __push_breaks();
 635 
 636         __merge_gotos(loop_name, NULL);
 637 
 638         extra_sm = __extra_handle_canonical_loops(stmt, &stree);
 639         __in_pre_condition++;
 640         __pass_to_client(stmt, PRELOOP_HOOK);
 641         __split_whole_condition(stmt->iterator_pre_condition);
 642         __in_pre_condition--;
 643         FOR_EACH_SM(stree, sm) {
 644                 set_state(sm->owner, sm->name, sm->sym, sm->state);
 645         } END_FOR_EACH_SM(sm);
 646         free_stree(&stree);
 647         if (extra_sm)
 648                 extra_sm = get_sm_state(extra_sm->owner, extra_sm->name, extra_sm->sym);
 649 
 650         if (option_assume_loops)
 651                 once_through = 1;
 652 
 653         __split_stmt(stmt->iterator_statement);
 654         if (is_forever_loop(stmt)) {
 655                 __merge_continues();
 656                 __save_gotos(loop_name, NULL);
 657 
 658                 __push_fake_cur_stree();
 659                 __split_stmt(stmt->iterator_post_statement);
 660                 stree = __pop_fake_cur_stree();
 661 
 662                 __discard_false_states();
 663                 __use_breaks();
 664 
 665                 if (!__path_is_null())
 666                         __merge_stree_into_cur(stree);
 667                 free_stree(&stree);
 668         } else {
 669                 __merge_continues();
 670                 unchanged = __iterator_unchanged(extra_sm);
 671                 __split_stmt(stmt->iterator_post_statement);
 672                 __prev_stmt = stmt->iterator_post_statement;
 673                 __cur_stmt = stmt;
 674 
 675                 __save_gotos(loop_name, NULL);
 676                 __in_pre_condition++;
 677                 __split_whole_condition(stmt->iterator_pre_condition);
 678                 __in_pre_condition--;
 679                 nullify_path();
 680                 __merge_false_states();
 681                 if (once_through)
 682                         __discard_false_states();
 683                 else
 684                         __merge_false_states();
 685 
 686                 if (extra_sm && unchanged)
 687                         __extra_pre_loop_hook_after(extra_sm,
 688                                                 stmt->iterator_post_statement,
 689                                                 stmt->iterator_pre_condition);
 690                 __merge_breaks();
 691         }
 692         loop_count--;
 693 }
 694 
 695 /*
 696  * Post loops are do {} while();
 697  */
 698 static void handle_post_loop(struct statement *stmt)
 699 {
 700         char *loop_name;
 701 
 702         loop_name = get_loop_name(loop_num);
 703         loop_num++;
 704         loop_count++;
 705 
 706         __push_continues();
 707         __push_breaks();
 708         __merge_gotos(loop_name, NULL);
 709         __split_stmt(stmt->iterator_statement);
 710         __merge_continues();
 711         if (!is_zero(stmt->iterator_post_condition))
 712                 __save_gotos(loop_name, NULL);
 713 
 714         if (is_forever_loop(stmt)) {
 715                 __use_breaks();
 716         } else {
 717                 __split_whole_condition(stmt->iterator_post_condition);
 718                 __use_false_states();
 719                 __merge_breaks();
 720         }
 721         loop_count--;
 722 }
 723 
 724 static int empty_statement(struct statement *stmt)
 725 {
 726         if (!stmt)
 727                 return 0;
 728         if (stmt->type == STMT_EXPRESSION && !stmt->expression)
 729                 return 1;
 730         return 0;
 731 }
 732 
 733 static int last_stmt_on_same_line(void)
 734 {
 735         struct statement *stmt;
 736         int i = 0;
 737 
 738         FOR_EACH_PTR_REVERSE(big_statement_stack, stmt) {
 739                 if (!i++)
 740                         continue;
 741                 if  (stmt->pos.line == get_lineno())
 742                         return 1;
 743                 return 0;
 744         } END_FOR_EACH_PTR_REVERSE(stmt);
 745         return 0;
 746 }
 747 
 748 static void split_asm_constraints(struct expression_list *expr_list)
 749 {
 750         struct expression *expr;
 751         int state = 0;
 752 
 753         FOR_EACH_PTR(expr_list, expr) {
 754                 switch (state) {
 755                 case 0: /* identifier */
 756                 case 1: /* constraint */
 757                         state++;
 758                         continue;
 759                 case 2: /* expression */
 760                         state = 0;
 761                         __split_expr(expr);
 762                         continue;
 763                 }
 764         } END_FOR_EACH_PTR(expr);
 765 }
 766 
 767 static int is_case_val(struct statement *stmt, sval_t sval)
 768 {
 769         sval_t case_sval;
 770 
 771         if (stmt->type != STMT_CASE)
 772                 return 0;
 773         if (!stmt->case_expression) {
 774                 __set_default();
 775                 return 1;
 776         }
 777         if (!get_value(stmt->case_expression, &case_sval))
 778                 return 0;
 779         if (case_sval.value == sval.value)
 780                 return 1;
 781         return 0;
 782 }
 783 
 784 static struct range_list *get_case_rl(struct expression *switch_expr,
 785                                       struct expression *case_expr,
 786                                       struct expression *case_to)
 787 {
 788         sval_t start, end;
 789         struct range_list *rl = NULL;
 790         struct symbol *switch_type;
 791 
 792         switch_type = get_type(switch_expr);
 793         if (get_value(case_to, &end) && get_value(case_expr, &start)) {
 794                 start = sval_cast(switch_type, start);
 795                 end = sval_cast(switch_type, end);
 796                 add_range(&rl, start, end);
 797         } else if (get_value(case_expr, &start)) {
 798                 start = sval_cast(switch_type, start);
 799                 add_range(&rl, start, start);
 800         }
 801 
 802         return rl;
 803 }
 804 
 805 static void split_known_switch(struct statement *stmt, sval_t sval)
 806 {
 807         struct statement *tmp;
 808         struct range_list *rl;
 809 
 810         __split_expr(stmt->switch_expression);
 811         sval = sval_cast(get_type(stmt->switch_expression), sval);
 812 
 813         push_expression(&switch_expr_stack, stmt->switch_expression);
 814         __save_switch_states(top_expression(switch_expr_stack));
 815         nullify_path();
 816         __push_default();
 817         __push_breaks();
 818 
 819         stmt = stmt->switch_statement;
 820 
 821         __push_scope_hooks();
 822         FOR_EACH_PTR(stmt->stmts, tmp) {
 823                 __smatch_lineno = tmp->pos.line;
 824                 if (is_case_val(tmp, sval)) {
 825                         rl = alloc_rl(sval, sval);
 826                         __merge_switches(top_expression(switch_expr_stack), rl);
 827                         __pass_case_to_client(top_expression(switch_expr_stack), rl);
 828                 }
 829                 if (__path_is_null())
 830                         continue;
 831                 __split_stmt(tmp);
 832                 if (__path_is_null()) {
 833                         __set_default();
 834                         goto out;
 835                 }
 836         } END_FOR_EACH_PTR(tmp);
 837 out:
 838         __call_scope_hooks();
 839         if (!__pop_default())
 840                 __merge_switches(top_expression(switch_expr_stack), NULL);
 841         __discard_switches();
 842         __merge_breaks();
 843         pop_expression(&switch_expr_stack);
 844 }
 845 
 846 static void split_case(struct statement *stmt)
 847 {
 848         struct range_list *rl = NULL;
 849 
 850         expr_set_parent_stmt(stmt->case_expression, stmt);
 851         expr_set_parent_stmt(stmt->case_to, stmt);
 852 
 853         rl = get_case_rl(top_expression(switch_expr_stack),
 854                          stmt->case_expression, stmt->case_to);
 855         while (stmt->case_statement->type == STMT_CASE) {
 856                 struct range_list *tmp;
 857 
 858                 tmp = get_case_rl(top_expression(switch_expr_stack),
 859                                   stmt->case_statement->case_expression,
 860                                   stmt->case_statement->case_to);
 861                 if (!tmp)
 862                         break;
 863                 rl = rl_union(rl, tmp);
 864                 if (!stmt->case_expression)
 865                         __set_default();
 866                 stmt = stmt->case_statement;
 867         }
 868 
 869         __merge_switches(top_expression(switch_expr_stack), rl);
 870 
 871         if (!stmt->case_expression)
 872                 __set_default();
 873         __split_stmt(stmt->case_statement);
 874 }
 875 
 876 int time_parsing_function(void)
 877 {
 878         return ms_since(&fn_start_time) / 1000;
 879 }
 880 
 881 static int taking_too_long(void)




 882 {
 883         if ((ms_since(&outer_fn_start_time) / 1000) > 60 * 5) /* five minutes */

 884                 return 1;
 885         return 0;
 886 }
 887 
 888 static int is_last_stmt(struct statement *cur_stmt)
 889 {
 890         struct symbol *fn;
 891         struct statement *stmt;
 892 
 893         if (!cur_func_sym)
 894                 return 0;
 895         fn = get_base_type(cur_func_sym);
 896         if (!fn)
 897                 return 0;
 898         stmt = fn->stmt;
 899         if (!stmt)
 900                 stmt = fn->inline_stmt;
 901         if (!stmt || stmt->type != STMT_COMPOUND)
 902                 return 0;
 903         stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
 904         if (stmt && stmt->type == STMT_LABEL)
 905                 stmt = stmt->label_statement;
 906         if (stmt == cur_stmt)
 907                 return 1;
 908         return 0;
 909 }
 910 
 911 static void handle_backward_goto(struct statement *goto_stmt)
 912 {
 913         const char *goto_name, *label_name;
 914         struct statement *func_stmt;
 915         struct symbol *base_type = get_base_type(cur_func_sym);
 916         struct statement *tmp;
 917         int found = 0;
 918 
 919         if (!option_info)
 920                 return;
 921         if (last_goto_statement_handled)
 922                 return;
 923         last_goto_statement_handled = 1;
 924 
 925         if (!goto_stmt->goto_label ||
 926             goto_stmt->goto_label->type != SYM_LABEL ||
 927             !goto_stmt->goto_label->ident)
 928                 return;
 929         goto_name = goto_stmt->goto_label->ident->name;
 930 
 931         func_stmt = base_type->stmt;
 932         if (!func_stmt)
 933                 func_stmt = base_type->inline_stmt;
 934         if (!func_stmt)
 935                 return;
 936         if (func_stmt->type != STMT_COMPOUND)
 937                 return;
 938 
 939         FOR_EACH_PTR(func_stmt->stmts, tmp) {
 940                 if (!found) {
 941                         if (tmp->type != STMT_LABEL)
 942                                 continue;
 943                         if (!tmp->label_identifier ||
 944                             tmp->label_identifier->type != SYM_LABEL ||
 945                             !tmp->label_identifier->ident)
 946                                 continue;
 947                         label_name = tmp->label_identifier->ident->name;
 948                         if (strcmp(goto_name, label_name) != 0)
 949                                 continue;
 950                         found = 1;
 951                 }
 952                 __split_stmt(tmp);
 953         } END_FOR_EACH_PTR(tmp);
 954 }
 955 
 956 static void fake_a_return(void)
 957 {
 958         struct symbol *return_type;
 959 
 960         nullify_path();
 961         __unnullify_path();
 962 
 963         return_type = get_real_base_type(cur_func_sym);
 964         return_type = get_real_base_type(return_type);
 965         if (return_type != &void_ctype) {
 966                 __pass_to_client(unknown_value_expression(NULL), RETURN_HOOK);
 967                 nullify_path();
 968         }
 969 }
 970 
 971 static void fake_an_empty_default(struct position pos)
 972 {
 973         static struct statement none = {};
 974 
 975         none.pos = pos;
 976         none.type = STMT_NONE;
 977         __merge_switches(top_expression(switch_expr_stack), NULL);
 978         __split_stmt(&none);
 979 }
 980 
 981 static void split_compound(struct statement *stmt)
 982 {
 983         struct statement *prev = NULL;
 984         struct statement *cur = NULL;
 985         struct statement *next;
 986 
 987         __push_scope_hooks();
 988 
 989         FOR_EACH_PTR(stmt->stmts, next) {
 990                 /* just set them all ahead of time */
 991                 stmt_set_parent_stmt(next, stmt);
 992 
 993                 if (cur) {
 994                         __prev_stmt = prev;
 995                         __next_stmt = next;
 996                         __cur_stmt = cur;
 997                         __split_stmt(cur);
 998                 }
 999                 prev = cur;
1000                 cur = next;
1001         } END_FOR_EACH_PTR(next);
1002         if (cur) {
1003                 __prev_stmt = prev;
1004                 __cur_stmt = cur;
1005                 __next_stmt = NULL;
1006                 __split_stmt(cur);
1007         }
1008 
1009         /*
1010          * For function scope, then delay calling the scope hooks until the
1011          * end of function hooks can run.  I'm not positive this is the right
1012          * thing...
1013          */
1014         if (!is_last_stmt(cur))
1015                 __call_scope_hooks();
1016 }
1017 
1018 /*
1019  * This is a hack, work around for detecting empty functions.
1020  */
1021 static int need_delayed_scope_hooks(void)
1022 {
1023         struct symbol *fn = get_base_type(cur_func_sym);
1024         struct statement *stmt;
1025 
1026         if (!fn)
1027                 return 0;
1028         stmt = fn->stmt;
1029         if (!stmt)
1030                 stmt = fn->inline_stmt;
1031         if (stmt && stmt->type == STMT_COMPOUND)
1032                 return 1;
1033         return 0;
1034 }
1035 
1036 void __split_label_stmt(struct statement *stmt)
1037 {
1038         if (stmt->label_identifier &&
1039             stmt->label_identifier->type == SYM_LABEL &&
1040             stmt->label_identifier->ident) {
1041                 loop_count |= 0x0800000;
1042                 __merge_gotos(stmt->label_identifier->ident->name, stmt->label_identifier);
1043         }
1044 }
1045 
1046 static void find_asm_gotos(struct statement *stmt)
1047 {
1048         struct symbol *sym;
1049 
1050         FOR_EACH_PTR(stmt->asm_labels, sym) {
1051                 __save_gotos(sym->ident->name, sym);
1052         } END_FOR_EACH_PTR(sym);
1053 }
1054 
1055 void __split_stmt(struct statement *stmt)
1056 {
1057         sval_t sval;
1058 
1059         if (!stmt)
1060                 goto out;
1061 
1062         if (!__in_fake_assign)
1063                 __silence_warnings_for_stmt = false;
1064 
1065         if (__bail_on_rest_of_function || is_skipped_function())
1066                 return;
1067 
1068         if (out_of_memory() || taking_too_long()) {
1069                 struct timeval stop;
1070 
1071                 gettimeofday(&stop, NULL);
1072 
1073                 __bail_on_rest_of_function = 1;
1074                 final_pass = 1;
1075                 sm_perror("Function too hairy.  Giving up. %lu seconds",
1076                        stop.tv_sec - fn_start_time.tv_sec);
1077                 fake_a_return();
1078                 final_pass = 0;  /* turn off sm_msg() from here */
1079                 return;
1080         }
1081 
1082         add_ptr_list(&big_statement_stack, stmt);
1083         free_expression_stack(&big_expression_stack);
1084         set_position(stmt->pos);
1085         __pass_to_client(stmt, STMT_HOOK);
1086 
1087         switch (stmt->type) {
1088         case STMT_DECLARATION:
1089                 split_declaration(stmt->declaration);
1090                 break;
1091         case STMT_RETURN:
1092                 expr_set_parent_stmt(stmt->ret_value, stmt);
1093 
1094                 __split_expr(stmt->ret_value);
1095                 __pass_to_client(stmt->ret_value, RETURN_HOOK);
1096                 __process_post_op_stack();
1097                 nullify_path();
1098                 break;
1099         case STMT_EXPRESSION:
1100                 expr_set_parent_stmt(stmt->expression, stmt);
1101                 expr_set_parent_stmt(stmt->context, stmt);
1102 
1103                 __split_expr(stmt->expression);
1104                 break;
1105         case STMT_COMPOUND:
1106                 split_compound(stmt);
1107                 break;
1108         case STMT_IF:
1109                 stmt_set_parent_stmt(stmt->if_true, stmt);
1110                 stmt_set_parent_stmt(stmt->if_false, stmt);
1111                 expr_set_parent_stmt(stmt->if_conditional, stmt);
1112 
1113                 if (known_condition_true(stmt->if_conditional)) {
1114                         __split_stmt(stmt->if_true);
1115                         break;
1116                 }
1117                 if (known_condition_false(stmt->if_conditional)) {
1118                         __split_stmt(stmt->if_false);
1119                         break;
1120                 }
1121                 __split_whole_condition(stmt->if_conditional);
1122                 __split_stmt(stmt->if_true);
1123                 if (empty_statement(stmt->if_true) &&
1124                         last_stmt_on_same_line() &&
1125                         !get_macro_name(stmt->if_true->pos))
1126                         sm_warning("if();");
1127                 __push_true_states();
1128                 __use_false_states();
1129                 __split_stmt(stmt->if_false);
1130                 __merge_true_states();
1131                 break;
1132         case STMT_ITERATOR:
1133                 stmt_set_parent_stmt(stmt->iterator_pre_statement, stmt);
1134                 stmt_set_parent_stmt(stmt->iterator_statement, stmt);
1135                 stmt_set_parent_stmt(stmt->iterator_post_statement, stmt);
1136                 expr_set_parent_stmt(stmt->iterator_pre_condition, stmt);
1137                 expr_set_parent_stmt(stmt->iterator_post_condition, stmt);
1138 
1139                 if (stmt->iterator_pre_condition)
1140                         handle_pre_loop(stmt);
1141                 else if (stmt->iterator_post_condition)
1142                         handle_post_loop(stmt);
1143                 else {
1144                         // these are for(;;) type loops.
1145                         handle_pre_loop(stmt);
1146                 }
1147                 break;
1148         case STMT_SWITCH:
1149                 stmt_set_parent_stmt(stmt->switch_statement, stmt);
1150                 expr_set_parent_stmt(stmt->switch_expression, stmt);
1151 
1152                 if (get_value(stmt->switch_expression, &sval)) {
1153                         split_known_switch(stmt, sval);
1154                         break;
1155                 }
1156                 __split_expr(stmt->switch_expression);
1157                 push_expression(&switch_expr_stack, stmt->switch_expression);
1158                 __save_switch_states(top_expression(switch_expr_stack));
1159                 nullify_path();
1160                 __push_default();
1161                 __push_breaks();
1162                 __split_stmt(stmt->switch_statement);
1163                 if (!__pop_default() && have_remaining_cases())
1164                         fake_an_empty_default(stmt->pos);
1165                 __discard_switches();
1166                 __merge_breaks();
1167                 pop_expression(&switch_expr_stack);
1168                 break;
1169         case STMT_CASE:
1170                 split_case(stmt);
1171                 break;
1172         case STMT_LABEL:
1173                 __split_label_stmt(stmt);
1174                 __split_stmt(stmt->label_statement);
1175                 break;
1176         case STMT_GOTO:
1177                 expr_set_parent_stmt(stmt->goto_expression, stmt);
1178 
1179                 __split_expr(stmt->goto_expression);
1180                 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
1181                         if (!strcmp(stmt->goto_label->ident->name, "break")) {
1182                                 __process_breaks();
1183                         } else if (!strcmp(stmt->goto_label->ident->name,
1184                                            "continue")) {
1185                                 __process_continues();
1186                         }
1187                 } else if (stmt->goto_label &&
1188                            stmt->goto_label->type == SYM_LABEL &&
1189                            stmt->goto_label->ident) {
1190                         __save_gotos(stmt->goto_label->ident->name, stmt->goto_label);
1191                 }
1192                 nullify_path();
1193                 if (is_last_stmt(stmt))
1194                         handle_backward_goto(stmt);
1195                 break;
1196         case STMT_NONE:
1197                 break;
1198         case STMT_ASM:
1199                 expr_set_parent_stmt(stmt->asm_string, stmt);
1200 
1201                 find_asm_gotos(stmt);
1202                 __pass_to_client(stmt, ASM_HOOK);
1203                 __split_expr(stmt->asm_string);
1204                 split_asm_constraints(stmt->asm_outputs);
1205                 split_asm_constraints(stmt->asm_inputs);
1206                 split_asm_constraints(stmt->asm_clobbers);
1207                 break;
1208         case STMT_CONTEXT:
1209                 break;
1210         case STMT_RANGE:
1211                 __split_expr(stmt->range_expression);
1212                 __split_expr(stmt->range_low);
1213                 __split_expr(stmt->range_high);
1214                 break;
1215         }
1216         __pass_to_client(stmt, STMT_HOOK_AFTER);
1217 out:
1218         __process_post_op_stack();
1219 }
1220 
1221 static void split_expr_list(struct expression_list *expr_list, struct expression *parent)
1222 {
1223         struct expression *expr;
1224 
1225         FOR_EACH_PTR(expr_list, expr) {
1226                 expr_set_parent_expr(expr, parent);
1227                 __split_expr(expr);
1228                 __process_post_op_stack();
1229         } END_FOR_EACH_PTR(expr);
1230 }
1231 
1232 static void split_sym(struct symbol *sym)
1233 {
1234         if (!sym)
1235                 return;
1236         if (!(sym->namespace & NS_SYMBOL))
1237                 return;
1238 
1239         __split_stmt(sym->stmt);
1240         __split_expr(sym->array_size);
1241         split_symlist(sym->arguments);
1242         split_symlist(sym->symbol_list);
1243         __split_stmt(sym->inline_stmt);
1244         split_symlist(sym->inline_symbol_list);
1245 }
1246 
1247 static void split_symlist(struct symbol_list *sym_list)
1248 {
1249         struct symbol *sym;
1250 
1251         FOR_EACH_PTR(sym_list, sym) {
1252                 split_sym(sym);
1253         } END_FOR_EACH_PTR(sym);
1254 }
1255 
1256 typedef void (fake_cb)(struct expression *expr);
1257 
1258 static int member_to_number(struct expression *expr, struct ident *member)
1259 {
1260         struct symbol *type, *tmp;
1261         char *name;
1262         int i;
1263 
1264         if (!member)
1265                 return -1;
1266         name = member->name;
1267 
1268         type = get_type(expr);
1269         if (!type || type->type != SYM_STRUCT)
1270                 return -1;
1271 
1272         i = -1;
1273         FOR_EACH_PTR(type->symbol_list, tmp) {
1274                 i++;
1275                 if (!tmp->ident)
1276                         continue;
1277                 if (strcmp(name, tmp->ident->name) == 0)
1278                         return i;
1279         } END_FOR_EACH_PTR(tmp);
1280         return -1;
1281 }
1282 
1283 static struct ident *number_to_member(struct expression *expr, int num)
1284 {
1285         struct symbol *type, *member;
1286         int i = 0;
1287 
1288         type = get_type(expr);
1289         if (!type || type->type != SYM_STRUCT)
1290                 return NULL;
1291 
1292         FOR_EACH_PTR(type->symbol_list, member) {
1293                 if (i == num)
1294                         return member->ident;
1295                 i++;
1296         } END_FOR_EACH_PTR(member);
1297         return NULL;
1298 }
1299 
1300 static void fake_element_assigns_helper(struct expression *array, struct expression_list *expr_list, fake_cb *fake_cb);
1301 
1302 static void set_inner_struct_members(struct expression *expr, struct symbol *member)
1303 {
1304         struct expression *edge_member, *assign;
1305         struct symbol *base = get_real_base_type(member);
1306         struct symbol *tmp;
1307 
1308         if (member->ident)
1309                 expr = member_expression(expr, '.', member->ident);
1310 
1311         FOR_EACH_PTR(base->symbol_list, tmp) {
1312                 struct symbol *type;
1313 
1314                 type = get_real_base_type(tmp);
1315                 if (!type)
1316                         continue;
1317 
1318                 edge_member = member_expression(expr, '.', tmp->ident);
1319                 if (get_extra_state(edge_member))
1320                         continue;
1321 
1322                 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
1323                         set_inner_struct_members(expr, tmp);
1324                         continue;
1325                 }
1326 
1327                 if (!tmp->ident)
1328                         continue;
1329 
1330                 assign = assign_expression(edge_member, '=', zero_expr());
1331                 __split_expr(assign);
1332         } END_FOR_EACH_PTR(tmp);
1333 
1334 
1335 }
1336 
1337 static void set_unset_to_zero(struct symbol *type, struct expression *expr)
1338 {
1339         struct symbol *tmp;
1340         struct expression *member = NULL;
1341         struct expression *assign;
1342         int op = '*';
1343 
1344         if (expr->type == EXPR_PREOP && expr->op == '&') {
1345                 expr = strip_expr(expr->unop);
1346                 op = '.';
1347         }
1348 
1349         FOR_EACH_PTR(type->symbol_list, tmp) {
1350                 type = get_real_base_type(tmp);
1351                 if (!type)
1352                         continue;
1353 
1354                 if (tmp->ident) {
1355                         member = member_expression(expr, op, tmp->ident);
1356                         if (get_extra_state(member))
1357                                 continue;
1358                 }
1359 
1360                 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
1361                         set_inner_struct_members(expr, tmp);
1362                         continue;
1363                 }
1364                 if (type->type == SYM_ARRAY)
1365                         continue;
1366                 if (!tmp->ident)
1367                         continue;
1368 
1369                 assign = assign_expression(member, '=', zero_expr());
1370                 __split_expr(assign);
1371         } END_FOR_EACH_PTR(tmp);
1372 }
1373 
1374 static void fake_member_assigns_helper(struct expression *symbol, struct expression_list *members, fake_cb *fake_cb)
1375 {
1376         struct expression *deref, *assign, *tmp, *right;
1377         struct symbol *struct_type, *type;
1378         struct ident *member;
1379         int member_idx;
1380 
1381         struct_type = get_type(symbol);
1382         if (!struct_type ||
1383             (struct_type->type != SYM_STRUCT && struct_type->type != SYM_UNION))
1384                 return;
1385 
1386         /*
1387          * We're parsing an initializer that could look something like this:
1388          * struct foo foo = {
1389          *      42,
1390          *      .whatever.xxx = 11,
1391          *      .zzz = 12,
1392          * };
1393          *
1394          * So what we have here is a list with 42, .whatever, and .zzz.  We need
1395          * to break it up into left and right sides of the assignments.
1396          *
1397          */
1398         member_idx = 0;
1399         FOR_EACH_PTR(members, tmp) {
1400                 deref = NULL;
1401                 if (tmp->type == EXPR_IDENTIFIER) {
1402                         member_idx = member_to_number(symbol, tmp->expr_ident);
1403                         while (tmp->type == EXPR_IDENTIFIER) {
1404                                 member = tmp->expr_ident;
1405                                 tmp = tmp->ident_expression;
1406                                 if (deref)
1407                                         deref = member_expression(deref, '.', member);
1408                                 else
1409                                         deref = member_expression(symbol, '.', member);
1410                         }
1411                 } else {
1412                         member = number_to_member(symbol, member_idx);
1413                         deref = member_expression(symbol, '.', member);
1414                 }
1415                 right = tmp;
1416                 member_idx++;
1417                 if (right->type == EXPR_INITIALIZER) {
1418                         type = get_type(deref);
1419                         if (type && type->type == SYM_ARRAY)
1420                                 fake_element_assigns_helper(deref, right->expr_list, fake_cb);
1421                         else
1422                                 fake_member_assigns_helper(deref, right->expr_list, fake_cb);
1423                 } else {
1424                         assign = assign_expression(deref, '=', right);
1425                         fake_cb(assign);
1426                 }
1427         } END_FOR_EACH_PTR(tmp);
1428 
1429         set_unset_to_zero(struct_type, symbol);
1430 }
1431 
1432 static void fake_member_assigns(struct symbol *sym, fake_cb *fake_cb)
1433 {
1434         fake_member_assigns_helper(symbol_expression(sym),
1435                                    sym->initializer->expr_list, fake_cb);
1436 }
1437 
1438 static void fake_element_assigns_helper(struct expression *array, struct expression_list *expr_list, fake_cb *fake_cb)
1439 {
1440         struct expression *offset, *binop, *assign, *tmp;
1441         struct symbol *type;
1442         int idx;
1443 
1444         if (ptr_list_size((struct ptr_list *)expr_list) > 1000)
1445                 return;
1446 
1447         idx = 0;
1448         FOR_EACH_PTR(expr_list, tmp) {
1449                 if (tmp->type == EXPR_INDEX) {
1450                         if (tmp->idx_from != tmp->idx_to)
1451                                 return;
1452                         idx = tmp->idx_from;
1453                         if (!tmp->idx_expression)
1454                                 goto next;
1455                         tmp = tmp->idx_expression;
1456                 }
1457                 offset = value_expr(idx);
1458                 binop = array_element_expression(array, offset);
1459                 if (tmp->type == EXPR_INITIALIZER) {
1460                         type = get_type(binop);
1461                         if (type && type->type == SYM_ARRAY)
1462                                 fake_element_assigns_helper(binop, tmp->expr_list, fake_cb);
1463                         else
1464                                 fake_member_assigns_helper(binop, tmp->expr_list, fake_cb);
1465                 } else {
1466                         assign = assign_expression(binop, '=', tmp);
1467                         fake_cb(assign);
1468                 }
1469 next:
1470                 idx++;
1471         } END_FOR_EACH_PTR(tmp);
1472 }
1473 
1474 static void fake_element_assigns(struct symbol *sym, fake_cb *fake_cb)
1475 {
1476         fake_element_assigns_helper(symbol_expression(sym), sym->initializer->expr_list, fake_cb);
1477 }
1478 
1479 static void fake_assign_expr(struct symbol *sym)
1480 {
1481         struct expression *assign, *symbol;
1482 
1483         symbol = symbol_expression(sym);
1484         assign = assign_expression(symbol, '=', sym->initializer);
1485         __split_expr(assign);
1486 }
1487 
1488 static void do_initializer_stuff(struct symbol *sym)
1489 {
1490         if (!sym->initializer)
1491                 return;
1492 
1493         if (sym->initializer->type == EXPR_INITIALIZER) {
1494                 if (get_real_base_type(sym)->type == SYM_ARRAY)
1495                         fake_element_assigns(sym, __split_expr);
1496                 else
1497                         fake_member_assigns(sym, __split_expr);
1498         } else {
1499                 fake_assign_expr(sym);
1500         }
1501 }
1502 
1503 static void split_declaration(struct symbol_list *sym_list)
1504 {
1505         struct symbol *sym;
1506 
1507         FOR_EACH_PTR(sym_list, sym) {
1508                 __pass_to_client(sym, DECLARATION_HOOK);
1509                 do_initializer_stuff(sym);
1510                 split_sym(sym);
1511         } END_FOR_EACH_PTR(sym);
1512 }
1513 
1514 static void call_global_assign_hooks(struct expression *assign)
1515 {
1516         __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
1517 }
1518 
1519 static void fake_global_assign(struct symbol *sym)
1520 {
1521         struct expression *assign, *symbol;
1522 
1523         if (get_real_base_type(sym)->type == SYM_ARRAY) {
1524                 if (sym->initializer && sym->initializer->type == EXPR_INITIALIZER) {
1525                         fake_element_assigns(sym, call_global_assign_hooks);
1526                 } else if (sym->initializer) {
1527                         symbol = symbol_expression(sym);
1528                         assign = assign_expression(symbol, '=', sym->initializer);
1529                         __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
1530                 } else {
1531                         fake_element_assigns_helper(symbol_expression(sym), NULL, call_global_assign_hooks);
1532                 }
1533         } else if (get_real_base_type(sym)->type == SYM_STRUCT) {
1534                 if (sym->initializer && sym->initializer->type == EXPR_INITIALIZER) {
1535                         fake_member_assigns(sym, call_global_assign_hooks);
1536                 } else if (sym->initializer) {
1537                         symbol = symbol_expression(sym);
1538                         assign = assign_expression(symbol, '=', sym->initializer);
1539                         __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
1540                 } else {
1541                         fake_member_assigns_helper(symbol_expression(sym), NULL, call_global_assign_hooks);
1542                 }
1543         } else {
1544                 symbol = symbol_expression(sym);
1545                 if (sym->initializer) {
1546                         assign = assign_expression(symbol, '=', sym->initializer);
1547                         __split_expr(assign);
1548                 } else {
1549                         assign = assign_expression(symbol, '=', zero_expr());
1550                 }
1551                 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
1552         }
1553 }
1554 
1555 static void start_function_definition(struct symbol *sym)
1556 {
1557         __in_function_def = 1;
1558         __pass_to_client(sym, FUNC_DEF_HOOK);
1559         __in_function_def = 0;
1560         __pass_to_client(sym, AFTER_DEF_HOOK);
1561 
1562 }
1563 
1564 static void split_function(struct symbol *sym)
1565 {
1566         struct symbol *base_type = get_base_type(sym);
1567         struct timeval stop;
1568 
1569         if (!base_type->stmt && !base_type->inline_stmt)
1570                 return;
1571 
1572         gettimeofday(&outer_fn_start_time, NULL);
1573         gettimeofday(&fn_start_time, NULL);
1574         cur_func_sym = sym;
1575         if (sym->ident)
1576                 cur_func = sym->ident->name;
1577         set_position(sym->pos);
1578         loop_count = 0;
1579         last_goto_statement_handled = 0;
1580         sm_debug("new function:  %s\n", cur_func);
1581         __stree_id = 0;
1582         if (option_two_passes) {
1583                 __unnullify_path();
1584                 loop_num = 0;
1585                 final_pass = 0;
1586                 start_function_definition(sym);
1587                 __split_stmt(base_type->stmt);
1588                 __split_stmt(base_type->inline_stmt);
1589                 nullify_path();
1590         }
1591         __unnullify_path();
1592         loop_num = 0;
1593         final_pass = 1;
1594         start_function_definition(sym);
1595         __split_stmt(base_type->stmt);
1596         __split_stmt(base_type->inline_stmt);
1597         __pass_to_client(sym, END_FUNC_HOOK);
1598         if (need_delayed_scope_hooks())
1599                 __call_scope_hooks();
1600         __pass_to_client(sym, AFTER_FUNC_HOOK);
1601 
1602         clear_all_states();
1603 
1604         gettimeofday(&stop, NULL);
1605         if (option_time && stop.tv_sec - fn_start_time.tv_sec > 2) {
1606                 final_pass++;
1607                 sm_msg("func_time: %lu", stop.tv_sec - fn_start_time.tv_sec);
1608                 final_pass--;
1609         }
1610         cur_func_sym = NULL;
1611         cur_func = NULL;
1612         free_data_info_allocs();
1613         free_expression_stack(&switch_expr_stack);
1614         __free_ptr_list((struct ptr_list **)&big_statement_stack);
1615         __bail_on_rest_of_function = 0;
1616 }
1617 
1618 static void save_flow_state(void)
1619 {
1620         __add_ptr_list(&backup, INT_PTR(loop_num << 2), 0);
1621         __add_ptr_list(&backup, INT_PTR(loop_count << 2), 0);
1622         __add_ptr_list(&backup, INT_PTR(final_pass << 2), 0);
1623 
1624         __add_ptr_list(&backup, big_statement_stack, 0);
1625         __add_ptr_list(&backup, big_expression_stack, 0);
1626         __add_ptr_list(&backup, big_condition_stack, 0);
1627         __add_ptr_list(&backup, switch_expr_stack, 0);
1628 
1629         __add_ptr_list(&backup, cur_func_sym, 0);
1630 
1631         __add_ptr_list(&backup, __prev_stmt, 0);
1632         __add_ptr_list(&backup, __cur_stmt, 0);
1633         __add_ptr_list(&backup, __next_stmt, 0);
1634 
1635 }
1636 
1637 static void *pop_backup(void)
1638 {
1639         void *ret;
1640 
1641         ret = last_ptr_list(backup);
1642         delete_ptr_list_last(&backup);
1643         return ret;
1644 }
1645 
1646 static void restore_flow_state(void)
1647 {
1648         __next_stmt = pop_backup();
1649         __cur_stmt = pop_backup();
1650         __prev_stmt = pop_backup();
1651 
1652         cur_func_sym = pop_backup();
1653         switch_expr_stack = pop_backup();
1654         big_condition_stack = pop_backup();
1655         big_expression_stack = pop_backup();
1656         big_statement_stack = pop_backup();
1657         final_pass = PTR_INT(pop_backup()) >> 2;
1658         loop_count = PTR_INT(pop_backup()) >> 2;
1659         loop_num = PTR_INT(pop_backup()) >> 2;
1660 }
1661 
1662 static void parse_inline(struct expression *call)
1663 {
1664         struct symbol *base_type;
1665         char *cur_func_bak = cur_func;  /* not aligned correctly for backup */
1666         struct timeval time_backup = fn_start_time;
1667         struct expression *orig_inline = __inline_fn;
1668         int orig_budget;
1669 
1670         if (out_of_memory() || taking_too_long())
1671                 return;
1672 
1673         save_flow_state();
1674 
1675         __pass_to_client(call, INLINE_FN_START);
1676         final_pass = 0;  /* don't print anything */
1677         __inline_fn = call;
1678         orig_budget = inline_budget;
1679         inline_budget = inline_budget - 5;
1680 
1681         base_type = get_base_type(call->fn->symbol);
1682         cur_func_sym = call->fn->symbol;
1683         if (call->fn->symbol->ident)
1684                 cur_func = call->fn->symbol->ident->name;
1685         else
1686                 cur_func = NULL;
1687         set_position(call->fn->symbol->pos);
1688 
1689         save_all_states();
1690         big_statement_stack = NULL;
1691         big_expression_stack = NULL;
1692         big_condition_stack = NULL;
1693         switch_expr_stack = NULL;
1694 
1695         sm_debug("inline function:  %s\n", cur_func);
1696         __unnullify_path();
1697         loop_num = 0;
1698         loop_count = 0;
1699         start_function_definition(call->fn->symbol);
1700         __split_stmt(base_type->stmt);
1701         __split_stmt(base_type->inline_stmt);
1702         __pass_to_client(call->fn->symbol, END_FUNC_HOOK);
1703         __pass_to_client(call->fn->symbol, AFTER_FUNC_HOOK);
1704 
1705         free_expression_stack(&switch_expr_stack);
1706         __free_ptr_list((struct ptr_list **)&big_statement_stack);
1707         nullify_path();
1708         free_goto_stack();
1709 
1710         restore_flow_state();
1711         fn_start_time = time_backup;
1712         cur_func = cur_func_bak;
1713 
1714         restore_all_states();
1715         set_position(call->pos);
1716         __inline_fn = orig_inline;
1717         inline_budget = orig_budget;
1718         __pass_to_client(call, INLINE_FN_END);
1719 }
1720 
1721 static struct symbol_list *inlines_called;
1722 static void add_inline_function(struct symbol *sym)
1723 {
1724         static struct symbol_list *already_added;
1725         struct symbol *tmp;
1726 
1727         FOR_EACH_PTR(already_added, tmp) {
1728                 if (tmp == sym)
1729                         return;
1730         } END_FOR_EACH_PTR(tmp);
1731 
1732         add_ptr_list(&already_added, sym);
1733         add_ptr_list(&inlines_called, sym);
1734 }
1735 
1736 static void process_inlines(void)
1737 {
1738         struct symbol *tmp;
1739 
1740         FOR_EACH_PTR(inlines_called, tmp) {
1741                 split_function(tmp);
1742         } END_FOR_EACH_PTR(tmp);
1743         free_ptr_list(&inlines_called);
1744 }
1745 
1746 static struct symbol *get_last_scoped_symbol(struct symbol_list *big_list, int use_static)
1747 {
1748         struct symbol *sym;
1749 
1750         FOR_EACH_PTR_REVERSE(big_list, sym) {
1751                 if (!sym->scope)
1752                         continue;
1753                 if (use_static && sym->ctype.modifiers & MOD_STATIC)
1754                         return sym;
1755                 if (!use_static && !(sym->ctype.modifiers & MOD_STATIC))
1756                         return sym;
1757         } END_FOR_EACH_PTR_REVERSE(sym);
1758 
1759         return NULL;
1760 }
1761 
1762 static bool interesting_function(struct symbol *sym)
1763 {
1764         static int prev_stream = -1;
1765         static bool prev_answer;
1766         const char *filename;
1767         int len;
1768 
1769         if (!(sym->ctype.modifiers & MOD_INLINE))
1770                 return true;
1771 
1772         if (sym->pos.stream == prev_stream)
1773                 return prev_answer;
1774 
1775         prev_stream = sym->pos.stream;
1776         prev_answer = false;
1777 
1778         filename = stream_name(sym->pos.stream);
1779         len = strlen(filename);
1780         if (len > 0 && filename[len - 1] == 'c')
1781                 prev_answer = true;
1782         return prev_answer;
1783 }
1784 
1785 static void split_inlines_in_scope(struct symbol *sym)
1786 {
1787         struct symbol *base;
1788         struct symbol_list *scope_list;
1789         int stream;
1790 
1791         scope_list = sym->scope->symbols;
1792         stream = sym->pos.stream;
1793 
1794         /* find the last static symbol in the file */
1795         FOR_EACH_PTR_REVERSE(scope_list, sym) {
1796                 if (sym->pos.stream != stream)
1797                         continue;
1798                 if (sym->type != SYM_NODE)
1799                         continue;
1800                 base = get_base_type(sym);
1801                 if (!base)
1802                         continue;
1803                 if (base->type != SYM_FN)
1804                         continue;
1805                 if (!base->inline_stmt)
1806                         continue;
1807                 if (!interesting_function(sym))
1808                         continue;
1809                 add_inline_function(sym);
1810         } END_FOR_EACH_PTR_REVERSE(sym);
1811 
1812         process_inlines();
1813 }
1814 
1815 static void split_inlines(struct symbol_list *sym_list)
1816 {
1817         struct symbol *sym;
1818 
1819         sym = get_last_scoped_symbol(sym_list, 0);
1820         if (sym)
1821                 split_inlines_in_scope(sym);
1822         sym = get_last_scoped_symbol(sym_list, 1);
1823         if (sym)
1824                 split_inlines_in_scope(sym);
1825 }
1826 
1827 static struct stree *clone_estates_perm(struct stree *orig)
1828 {
1829         struct stree *ret = NULL;
1830         struct sm_state *tmp;
1831 
1832         FOR_EACH_SM(orig, tmp) {
1833                 set_state_stree_perm(&ret, tmp->owner, tmp->name, tmp->sym, clone_estate_perm(tmp->state));
1834         } END_FOR_EACH_SM(tmp);
1835 
1836         return ret;
1837 }
1838 
1839 struct position last_pos;
1840 static void split_c_file_functions(struct symbol_list *sym_list)
1841 {
1842         struct symbol *sym;
1843 
1844         __unnullify_path();
1845         FOR_EACH_PTR(sym_list, sym) {
1846                 set_position(sym->pos);
1847                 if (sym->type != SYM_NODE || get_base_type(sym)->type != SYM_FN) {
1848                         __pass_to_client(sym, BASE_HOOK);
1849                         fake_global_assign(sym);
1850                 }
1851         } END_FOR_EACH_PTR(sym);
1852         global_states = clone_estates_perm(get_all_states_stree(SMATCH_EXTRA));
1853         nullify_path();
1854 
1855         FOR_EACH_PTR(sym_list, sym) {
1856                 set_position(sym->pos);
1857                 last_pos = sym->pos;
1858                 if (!interesting_function(sym))
1859                         continue;
1860                 if (sym->type == SYM_NODE && get_base_type(sym)->type == SYM_FN) {
1861                         split_function(sym);
1862                         process_inlines();
1863                 }
1864                 last_pos = sym->pos;
1865         } END_FOR_EACH_PTR(sym);
1866         split_inlines(sym_list);
1867         __pass_to_client(sym_list, END_FILE_HOOK);
1868 }
1869 
1870 static int final_before_fake;
1871 void init_fake_env(void)
1872 {
1873         if (!in_fake_env)
1874                 final_before_fake = final_pass;
1875         in_fake_env++;
1876         __push_fake_cur_stree();
1877         final_pass = 0;
1878 }
1879 
1880 void end_fake_env(void)
1881 {
1882         __pop_fake_cur_stree();
1883         in_fake_env--;
1884         if (!in_fake_env)
1885                 final_pass = final_before_fake;
1886 }
1887 
1888 static void open_output_files(char *base_file)
1889 {
1890         char buf[256];
1891 
1892         snprintf(buf, sizeof(buf), "%s.smatch", base_file);
1893         sm_outfd = fopen(buf, "w");
1894         if (!sm_outfd)
1895                 sm_fatal("Cannot open %s", buf);
1896 
1897         if (!option_info)
1898                 return;
1899 
1900         snprintf(buf, sizeof(buf), "%s.smatch.sql", base_file);
1901         sql_outfd = fopen(buf, "w");
1902         if (!sql_outfd)
1903                 sm_fatal("Error:  Cannot open %s", buf);
1904 
1905         snprintf(buf, sizeof(buf), "%s.smatch.caller_info", base_file);
1906         caller_info_fd = fopen(buf, "w");
1907         if (!caller_info_fd)
1908                 sm_fatal("Error:  Cannot open %s", buf);
1909 }
1910 
1911 void smatch(int argc, char **argv)
1912 {
1913         struct string_list *filelist = NULL;
1914         struct symbol_list *sym_list;
1915         struct timeval stop, start;
1916         char *path;
1917         int len;
1918 
1919         gettimeofday(&start, NULL);
1920 
1921         sparse_initialize(argc, argv, &filelist);
1922         set_valid_ptr_max();
1923         alloc_valid_ptr_rl();
1924         FOR_EACH_PTR_NOTAG(filelist, base_file) {
1925                 path = getcwd(NULL, 0);
1926                 free(full_base_file);
1927                 if (path) {
1928                         len = strlen(path) + 1 + strlen(base_file) + 1;
1929                         full_base_file = malloc(len);
1930                         snprintf(full_base_file, len, "%s/%s", path, base_file);
1931                 } else {
1932                         full_base_file = alloc_string(base_file);
1933                 }
1934                 if (option_file_output)
1935                         open_output_files(base_file);
1936                 sym_list = sparse_keep_tokens(base_file);
1937                 split_c_file_functions(sym_list);
1938         } END_FOR_EACH_PTR_NOTAG(base_file);
1939 
1940         gettimeofday(&stop, NULL);
1941 
1942         set_position(last_pos);

1943         if (option_time)
1944                 sm_msg("time: %lu", stop.tv_sec - start.tv_sec);
1945         if (option_mem)
1946                 sm_msg("mem: %luKb", get_max_memory());
1947 }
--- EOF ---