Print this page
11506 smatch resync


 179         expr = strip_expr(expr);
 180         if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->ident)
 181                 return NULL;
 182 
 183         sym = expr->symbol;
 184         if (!(sym->ctype.modifiers & MOD_TOPLEVEL))
 185                 return NULL;
 186 
 187         if (sym->ctype.modifiers & MOD_STATIC)
 188                 snprintf(buf, sizeof(buf), "%s %s", get_base_file(), sym->ident->name);
 189         else
 190                 snprintf(buf, sizeof(buf), "extern %s", sym->ident->name);
 191 
 192         return alloc_string(buf);
 193 }
 194 
 195 char *get_constraint_str(struct expression *expr)
 196 {
 197         char *name;
 198 

 199         if (!expr)
 200                 return NULL;
 201         if (expr->type == EXPR_CALL)
 202                 return get_func_constraint(expr);
 203         if (expr->type == EXPR_BINOP)
 204                 return expr_to_str(expr);
 205         name = get_toplevel_name(expr);
 206         if (name)
 207                 return name;
 208         return get_member_name(expr);
 209 }
 210 
 211 static int save_int_callback(void *_p, int argc, char **argv, char **azColName)
 212 {
 213         int *p = _p;
 214 
 215         *p = atoi(argv[0]);
 216         return 0;
 217 }
 218 


 324 
 325                 req_op = get_required_op(data_str, con_str);
 326                 free_string(con_str);
 327                 if (!req_op)
 328                         continue;
 329                 if (con->op == '<' || con->op == req_op) {
 330                         free_string(required);
 331                         required = NULL;
 332                         goto free_data;
 333                 }
 334         } END_FOR_EACH_PTR(con);
 335 
 336 free_data:
 337         free_string(data_str);
 338         return required;
 339 }
 340 
 341 struct string_list *saved_constraints;
 342 static void save_new_constraint(const char *con)
 343 {
 344         if (list_has_string(saved_constraints, con))
 345                 return;
 346         insert_string(&saved_constraints, con);
 347         sql_save_constraint(con);
 348 }
 349 
 350 static void handle_comparison(struct expression *left, int op, struct expression *right)
 351 {
 352         struct constraint_list *constraints;
 353         struct smatch_state *state;
 354         char *constraint;
 355         int constraint_id;
 356         int orig_op = op;
 357         sval_t sval;
 358 
 359         /* known values are handled in smatch extra */
 360         if (get_value(left, &sval) || get_value(right, &sval))
 361                 return;
 362 
 363         if (local_debug)
 364                 sm_msg("COMPARE: %s %s %s", expr_to_str(left), show_special(op), expr_to_str(right));
 365 
 366         constraint = get_constraint_str(right);
 367         if (!constraint)
 368                 return;
 369         if (local_debug)
 370                 sm_msg("EXPR: %s CONSTRAINT %s", expr_to_str(right), constraint);
 371         constraint_id = constraint_str_to_id(constraint);
 372         if (local_debug)
 373                 sm_msg("CONSTRAINT ID %d", constraint_id);
 374         if (constraint_id < 0)
 375                 save_new_constraint(constraint);
 376         free_string(constraint);
 377         if (constraint_id < 0)
 378                 return;
 379 
 380         constraints = get_constraints(left);
 381         constraints = clone_constraint_list(constraints);
 382         op = negate_gt(orig_op);
 383         add_constraint(&constraints, remove_unsigned_from_comparison(op), constraint_id);
 384         state = alloc_constraint_state(constraints);
 385 
 386         if (op == orig_op) {
 387                 if (local_debug)
 388                         sm_msg("SETTING %s true %s", expr_to_str(left), state->name);
 389                 set_true_false_states_expr(my_id, left, state, NULL);
 390         } else {
 391                 if (local_debug)
 392                         sm_msg("SETTING %s false %s", expr_to_str(left), state->name);
 393 
 394                 set_true_false_states_expr(my_id, left, NULL, state);
 395         }
 396 }
 397 
 398 static void match_condition(struct expression *expr)
 399 {
 400         if (expr->type != EXPR_COMPARE)
 401                 return;
 402 
 403         if (expr->op == SPECIAL_EQUAL ||
 404             expr->op == SPECIAL_NOTEQUAL)
 405                 return;
 406 
 407         handle_comparison(expr->left, expr->op, expr->right);
 408         handle_comparison(expr->right, flip_comparison(expr->op), expr->left);
 409 }
 410 
 411 struct constraint_list *get_constraints(struct expression *expr)
 412 {
 413         struct smatch_state *state;
 414 
 415         state = get_state_expr(my_id, expr);


 512 }
 513 
 514 static void db_returns_constrained(struct expression *expr, int param, char *key, char *value)
 515 {
 516         char *name;
 517         struct symbol *sym;
 518 
 519         name = return_state_to_var_sym(expr, param, key, &sym);
 520         if (!name || !sym)
 521                 goto free;
 522 
 523         set_state(my_id, name, sym, constraint_str_to_state(value));
 524 free:
 525         free_string(name);
 526 }
 527 
 528 void register_constraints(int id)
 529 {
 530         my_id = id;
 531 

 532         add_merge_hook(my_id, &merge_func);
 533         add_hook(&match_condition, CONDITION_HOOK);
 534 
 535         add_hook(&match_caller_info, FUNCTION_CALL_HOOK);
 536         add_member_info_callback(my_id, struct_member_callback);
 537         select_caller_info_hook(&set_param_constrained, CONSTRAINT);
 538 
 539         add_split_return_callback(print_return_implies_constrained);
 540         select_return_states_hook(CONSTRAINT, &db_returns_constrained);
 541 }


 179         expr = strip_expr(expr);
 180         if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->ident)
 181                 return NULL;
 182 
 183         sym = expr->symbol;
 184         if (!(sym->ctype.modifiers & MOD_TOPLEVEL))
 185                 return NULL;
 186 
 187         if (sym->ctype.modifiers & MOD_STATIC)
 188                 snprintf(buf, sizeof(buf), "%s %s", get_base_file(), sym->ident->name);
 189         else
 190                 snprintf(buf, sizeof(buf), "extern %s", sym->ident->name);
 191 
 192         return alloc_string(buf);
 193 }
 194 
 195 char *get_constraint_str(struct expression *expr)
 196 {
 197         char *name;
 198 
 199         expr = strip_expr(expr);
 200         if (!expr)
 201                 return NULL;
 202         if (expr->type == EXPR_CALL)
 203                 return get_func_constraint(expr);
 204         if (expr->type == EXPR_BINOP)
 205                 return expr_to_str(expr);
 206         name = get_toplevel_name(expr);
 207         if (name)
 208                 return name;
 209         return get_member_name(expr);
 210 }
 211 
 212 static int save_int_callback(void *_p, int argc, char **argv, char **azColName)
 213 {
 214         int *p = _p;
 215 
 216         *p = atoi(argv[0]);
 217         return 0;
 218 }
 219 


 325 
 326                 req_op = get_required_op(data_str, con_str);
 327                 free_string(con_str);
 328                 if (!req_op)
 329                         continue;
 330                 if (con->op == '<' || con->op == req_op) {
 331                         free_string(required);
 332                         required = NULL;
 333                         goto free_data;
 334                 }
 335         } END_FOR_EACH_PTR(con);
 336 
 337 free_data:
 338         free_string(data_str);
 339         return required;
 340 }
 341 
 342 struct string_list *saved_constraints;
 343 static void save_new_constraint(const char *con)
 344 {
 345         if (!insert_string(&saved_constraints, con))
 346                 return;

 347         sql_save_constraint(con);
 348 }
 349 
 350 static void handle_comparison(struct expression *left, int op, struct expression *right)
 351 {
 352         struct constraint_list *constraints;
 353         struct smatch_state *state;
 354         char *constraint;
 355         int constraint_id;
 356         int orig_op = op;
 357         sval_t sval;
 358 
 359         /* known values are handled in smatch extra */
 360         if (get_value(left, &sval) || get_value(right, &sval))
 361                 return;
 362 



 363         constraint = get_constraint_str(right);
 364         if (!constraint)
 365                 return;


 366         constraint_id = constraint_str_to_id(constraint);


 367         if (constraint_id < 0)
 368                 save_new_constraint(constraint);
 369         free_string(constraint);
 370         if (constraint_id < 0)
 371                 return;
 372 
 373         constraints = get_constraints(left);
 374         constraints = clone_constraint_list(constraints);
 375         op = negate_gt(orig_op);
 376         add_constraint(&constraints, remove_unsigned_from_comparison(op), constraint_id);
 377         state = alloc_constraint_state(constraints);
 378 
 379         if (op == orig_op)


 380                 set_true_false_states_expr(my_id, left, state, NULL);
 381         else



 382                 set_true_false_states_expr(my_id, left, NULL, state);

 383 }
 384 
 385 static void match_condition(struct expression *expr)
 386 {
 387         if (expr->type != EXPR_COMPARE)
 388                 return;
 389 
 390         if (expr->op == SPECIAL_EQUAL ||
 391             expr->op == SPECIAL_NOTEQUAL)
 392                 return;
 393 
 394         handle_comparison(expr->left, expr->op, expr->right);
 395         handle_comparison(expr->right, flip_comparison(expr->op), expr->left);
 396 }
 397 
 398 struct constraint_list *get_constraints(struct expression *expr)
 399 {
 400         struct smatch_state *state;
 401 
 402         state = get_state_expr(my_id, expr);


 499 }
 500 
 501 static void db_returns_constrained(struct expression *expr, int param, char *key, char *value)
 502 {
 503         char *name;
 504         struct symbol *sym;
 505 
 506         name = return_state_to_var_sym(expr, param, key, &sym);
 507         if (!name || !sym)
 508                 goto free;
 509 
 510         set_state(my_id, name, sym, constraint_str_to_state(value));
 511 free:
 512         free_string(name);
 513 }
 514 
 515 void register_constraints(int id)
 516 {
 517         my_id = id;
 518 
 519         set_dynamic_states(my_id);
 520         add_merge_hook(my_id, &merge_func);
 521         add_hook(&match_condition, CONDITION_HOOK);
 522 
 523         add_hook(&match_caller_info, FUNCTION_CALL_HOOK);
 524         add_member_info_callback(my_id, struct_member_callback);
 525         select_caller_info_hook(&set_param_constrained, CONSTRAINT);
 526 
 527         add_split_return_callback(print_return_implies_constrained);
 528         select_return_states_hook(CONSTRAINT, &db_returns_constrained);
 529 }