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 }
|