|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /** |
|
6 * Detects static initializers i.e. functions called during static initialization. |
|
7 */ |
|
8 |
|
9 require({ after_gcc_pass: "cfg" }); |
|
10 |
|
11 function process_tree(fn) { |
|
12 for each (let attr in translate_attributes(DECL_ATTRIBUTES(fn))) |
|
13 if (attr.name == "constructor") |
|
14 warning(pretty_func(fn) + " marked with constructor attribute\n"); |
|
15 |
|
16 if (decl_name_string(fn) != "__static_initialization_and_destruction_0") |
|
17 return; |
|
18 |
|
19 let cfg = function_decl_cfg(fn); |
|
20 for (let isn in cfg_isn_iterator(cfg)) { |
|
21 if (isn.tree_code() != GIMPLE_CALL) |
|
22 continue; |
|
23 let decl = gimple_call_fndecl(isn); |
|
24 let lhs = gimple_call_lhs(isn); |
|
25 if (lhs) { |
|
26 warning(pretty_var(lhs) + " defined by call to " + pretty_func(decl) + |
|
27 " during static initialization", location_of(lhs)); |
|
28 } else { |
|
29 let arg = constructorArg(isn); |
|
30 if (arg) |
|
31 warning(pretty_var(arg) + " defined by call to constructor " + pretty_func(decl) + |
|
32 " during static initialization", location_of(arg)); |
|
33 else |
|
34 warning(pretty_func(decl) + " called during static initialization", location_of(decl)); |
|
35 } |
|
36 } |
|
37 } |
|
38 |
|
39 function constructorArg(call) { |
|
40 let decl = gimple_call_fndecl(call); |
|
41 |
|
42 if (!DECL_CONSTRUCTOR_P(decl)) |
|
43 return null; |
|
44 |
|
45 let arg = gimple_call_arg_iterator(call).next(); |
|
46 if (TYPE_MAIN_VARIANT(TREE_TYPE(TREE_TYPE(arg))) != DECL_CONTEXT(decl)) |
|
47 throw new Error("malformed constructor call?!"); |
|
48 |
|
49 return arg.tree_code() == ADDR_EXPR ? TREE_OPERAND(arg, 0) : arg; |
|
50 } |
|
51 |
|
52 function pretty_func(fn) { |
|
53 return rfunc_string(rectify_function_decl(fn)); |
|
54 } |
|
55 |
|
56 function pretty_var(v) { |
|
57 return type_string(TREE_TYPE(v)) + " " + expr_display(v); |
|
58 } |