2 * Copyright (C) 2021 Oracle.
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.
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.
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
19 #include "smatch_extra.h"
22 static struct expr_fn_list
*deref_hooks
;
24 void add_dereference_hook(expr_func
*fn
)
26 add_ptr_list(&deref_hooks
, fn
);
29 static void call_deref_hooks(struct expression
*expr
)
31 if (__in_fake_assign
|| __in_fake_parameter_assign
)
36 call_expr_fns(deref_hooks
, expr
);
39 static void match_dereference(struct expression
*expr
)
41 struct expression
*p
, *tmp
;
43 if (expr
->type
!= EXPR_PREOP
||
46 p
= strip_expr(expr
->unop
);
51 tmp
= get_assigned_expr(p
);
59 * Note that we only care about address assignments because other
60 * dereferences would have been handled already.
62 p
= strip_expr(tmp
->unop
);
63 if (tmp
->type
!= EXPR_PREOP
|| tmp
->op
!= '&')
65 p
= strip_expr(tmp
->unop
);
66 if (p
->type
!= EXPR_DEREF
)
68 p
= strip_expr(p
->deref
);
69 if (p
->type
!= EXPR_PREOP
|| p
->op
!= '*')
71 p
= strip_expr(p
->unop
);
77 static void match_pointer_as_array(struct expression
*expr
)
81 call_deref_hooks(get_array_base(expr
));
84 static void set_param_dereferenced(struct expression
*call
, struct expression
*arg
, char *key
, char *unused
)
86 struct expression
*deref
;
88 deref
= gen_expression_from_key(arg
, key
);
92 call_deref_hooks(deref
);
95 void register_dereferences(int id
)
99 add_hook(&match_dereference
, DEREF_HOOK
);
100 add_hook(&match_pointer_as_array
, OP_HOOK
);
101 select_return_implies_hook_early(DEREFERENCE
, &set_param_dereferenced
);