2 * Copyright (C) 2018 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
21 #include "smatch_slist.h"
22 #include "smatch_extra.h"
28 bool is_nospec(struct expression
*expr
)
32 if (get_state_expr(my_id
, expr
) == &nospec
)
34 macro
= get_macro_name(expr
->pos
);
35 if (macro
&& strcmp(macro
, "array_index_nospec") == 0)
40 static void nospec_assign(struct expression
*expr
)
42 if (is_nospec(expr
->right
))
43 set_state_expr(my_id
, expr
->left
, &nospec
);
46 static void set_param_nospec(const char *name
, struct symbol
*sym
, char *key
, char *value
)
50 if (strcmp(key
, "*$") == 0)
51 snprintf(fullname
, sizeof(fullname
), "*%s", name
);
52 else if (strncmp(key
, "$", 1) == 0)
53 snprintf(fullname
, 256, "%s%s", name
, key
+ 1);
57 set_state(my_id
, fullname
, sym
, &nospec
);
60 static void match_call_info(struct expression
*expr
)
62 struct expression
*arg
;
65 FOR_EACH_PTR(expr
->args
, arg
) {
66 if (get_state_expr(my_id
, arg
) == &nospec
)
67 sql_insert_caller_info(expr
, NOSPEC
, i
, "$", "");
69 } END_FOR_EACH_PTR(arg
);
72 static void struct_member_callback(struct expression
*call
, int param
, char *printed_name
, struct sm_state
*sm
)
74 sql_insert_caller_info(call
, NOSPEC
, param
, printed_name
, "");
77 static void returned_struct_members(int return_id
, char *return_ranges
, struct expression
*expr
)
79 struct symbol
*returned_sym
;
81 const char *param_name
;
84 returned_sym
= expr_to_sym(expr
);
86 FOR_EACH_MY_SM(my_id
, __get_cur_stree(), sm
) {
87 param
= get_param_num_from_sym(sm
->sym
);
89 if (!returned_sym
|| returned_sym
!= sm
->sym
)
94 param_name
= get_param_name(sm
);
97 if (param
!= -1 && strcmp(param_name
, "$") == 0)
100 sql_insert_return_states(return_id
, return_ranges
, NOSPEC
, param
, param_name
, "");
101 } END_FOR_EACH_SM(sm
);
104 void check_nospec(int id
)
108 add_hook(&nospec_assign
, ASSIGNMENT_HOOK
);
110 select_caller_info_hook(set_param_nospec
, NOSPEC
);
113 add_hook(&match_call_info
, FUNCTION_CALL_HOOK
);
114 add_member_info_callback(my_id
, struct_member_callback
);
115 add_split_return_callback(&returned_struct_members
);