smatch_constraints.c (1f5207b7) smatch_constraints.c (efe51d0c)
1/*
2 * Copyright (C) 2017 Oracle.
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 *

--- 182 unchanged lines hidden (view full) ---

191
192 return alloc_string(buf);
193}
194
195char *get_constraint_str(struct expression *expr)
196{
197 char *name;
198
1/*
2 * Copyright (C) 2017 Oracle.
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 *

--- 182 unchanged lines hidden (view full) ---

191
192 return alloc_string(buf);
193}
194
195char *get_constraint_str(struct expression *expr)
196{
197 char *name;
198
199 expr = strip_expr(expr);
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)

--- 129 unchanged lines hidden (view full) ---

336free_data:
337 free_string(data_str);
338 return required;
339}
340
341struct string_list *saved_constraints;
342static void save_new_constraint(const char *con)
343{
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)

--- 129 unchanged lines hidden (view full) ---

337free_data:
338 free_string(data_str);
339 return required;
340}
341
342struct string_list *saved_constraints;
343static void save_new_constraint(const char *con)
344{
344 if (list_has_string(saved_constraints, con))
345 if (!insert_string(&saved_constraints, con))
345 return;
346 return;
346 insert_string(&saved_constraints, con);
347 sql_save_constraint(con);
348}
349
350static 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
347 sql_save_constraint(con);
348}
349
350static 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;
363 constraint = get_constraint_str(right);
364 if (!constraint)
365 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);
366 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
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
386 if (op == orig_op) {
387 if (local_debug)
388 sm_msg("SETTING %s true %s", expr_to_str(left), state->name);
379 if (op == orig_op)
389 set_true_false_states_expr(my_id, left, state, NULL);
380 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
381 else
394 set_true_false_states_expr(my_id, left, NULL, state);
382 set_true_false_states_expr(my_id, left, NULL, state);
395 }
396}
397
398static void match_condition(struct expression *expr)
399{
400 if (expr->type != EXPR_COMPARE)
401 return;
402
403 if (expr->op == SPECIAL_EQUAL ||

--- 120 unchanged lines hidden (view full) ---

524free:
525 free_string(name);
526}
527
528void register_constraints(int id)
529{
530 my_id = id;
531
383}
384
385static void match_condition(struct expression *expr)
386{
387 if (expr->type != EXPR_COMPARE)
388 return;
389
390 if (expr->op == SPECIAL_EQUAL ||

--- 120 unchanged lines hidden (view full) ---

511free:
512 free_string(name);
513}
514
515void register_constraints(int id)
516{
517 my_id = id;
518
519 set_dynamic_states(my_id);
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}
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}