aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/gcc-plugins/structleak_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/gcc-plugins/structleak_plugin.c')
-rw-r--r--scripts/gcc-plugins/structleak_plugin.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c
index 10292f791e99..e89be8f5c859 100644
--- a/scripts/gcc-plugins/structleak_plugin.c
+++ b/scripts/gcc-plugins/structleak_plugin.c
@@ -16,6 +16,7 @@
16 * Options: 16 * Options:
17 * -fplugin-arg-structleak_plugin-disable 17 * -fplugin-arg-structleak_plugin-disable
18 * -fplugin-arg-structleak_plugin-verbose 18 * -fplugin-arg-structleak_plugin-verbose
19 * -fplugin-arg-structleak_plugin-byref
19 * -fplugin-arg-structleak_plugin-byref-all 20 * -fplugin-arg-structleak_plugin-byref-all
20 * 21 *
21 * Usage: 22 * Usage:
@@ -26,7 +27,6 @@
26 * $ gcc -fplugin=./structleak_plugin.so test.c -O2 27 * $ gcc -fplugin=./structleak_plugin.so test.c -O2
27 * 28 *
28 * TODO: eliminate redundant initializers 29 * TODO: eliminate redundant initializers
29 * increase type coverage
30 */ 30 */
31 31
32#include "gcc-common.h" 32#include "gcc-common.h"
@@ -37,13 +37,18 @@
37__visible int plugin_is_GPL_compatible; 37__visible int plugin_is_GPL_compatible;
38 38
39static struct plugin_info structleak_plugin_info = { 39static struct plugin_info structleak_plugin_info = {
40 .version = "201607271510vanilla", 40 .version = "20190125vanilla",
41 .help = "disable\tdo not activate plugin\n" 41 .help = "disable\tdo not activate plugin\n"
42 "verbose\tprint all initialized variables\n", 42 "byref\tinit structs passed by reference\n"
43 "byref-all\tinit anything passed by reference\n"
44 "verbose\tprint all initialized variables\n",
43}; 45};
44 46
47#define BYREF_STRUCT 1
48#define BYREF_ALL 2
49
45static bool verbose; 50static bool verbose;
46static bool byref_all; 51static int byref;
47 52
48static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) 53static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
49{ 54{
@@ -118,6 +123,7 @@ static void initialize(tree var)
118 gimple_stmt_iterator gsi; 123 gimple_stmt_iterator gsi;
119 tree initializer; 124 tree initializer;
120 gimple init_stmt; 125 gimple init_stmt;
126 tree type;
121 127
122 /* this is the original entry bb before the forced split */ 128 /* this is the original entry bb before the forced split */
123 bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); 129 bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
@@ -148,11 +154,15 @@ static void initialize(tree var)
148 if (verbose) 154 if (verbose)
149 inform(DECL_SOURCE_LOCATION(var), 155 inform(DECL_SOURCE_LOCATION(var),
150 "%s variable will be forcibly initialized", 156 "%s variable will be forcibly initialized",
151 (byref_all && TREE_ADDRESSABLE(var)) ? "byref" 157 (byref && TREE_ADDRESSABLE(var)) ? "byref"
152 : "userspace"); 158 : "userspace");
153 159
154 /* build the initializer expression */ 160 /* build the initializer expression */
155 initializer = build_constructor(TREE_TYPE(var), NULL); 161 type = TREE_TYPE(var);
162 if (AGGREGATE_TYPE_P(type))
163 initializer = build_constructor(type, NULL);
164 else
165 initializer = fold_convert(type, integer_zero_node);
156 166
157 /* build the initializer stmt */ 167 /* build the initializer stmt */
158 init_stmt = gimple_build_assign(var, initializer); 168 init_stmt = gimple_build_assign(var, initializer);
@@ -184,13 +194,13 @@ static unsigned int structleak_execute(void)
184 if (!auto_var_in_fn_p(var, current_function_decl)) 194 if (!auto_var_in_fn_p(var, current_function_decl))
185 continue; 195 continue;
186 196
187 /* only care about structure types */ 197 /* only care about structure types unless byref-all */
188 if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) 198 if (byref != BYREF_ALL && TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
189 continue; 199 continue;
190 200
191 /* if the type is of interest, examine the variable */ 201 /* if the type is of interest, examine the variable */
192 if (TYPE_USERSPACE(type) || 202 if (TYPE_USERSPACE(type) ||
193 (byref_all && TREE_ADDRESSABLE(var))) 203 (byref && TREE_ADDRESSABLE(var)))
194 initialize(var); 204 initialize(var);
195 } 205 }
196 206
@@ -232,8 +242,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc
232 verbose = true; 242 verbose = true;
233 continue; 243 continue;
234 } 244 }
245 if (!strcmp(argv[i].key, "byref")) {
246 byref = BYREF_STRUCT;
247 continue;
248 }
235 if (!strcmp(argv[i].key, "byref-all")) { 249 if (!strcmp(argv[i].key, "byref-all")) {
236 byref_all = true; 250 byref = BYREF_ALL;
237 continue; 251 continue;
238 } 252 }
239 error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); 253 error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);