зеркало из https://github.com/mozilla/pjs.git
Bug 573786 - Script to detect static initializers r=taras
This commit is contained in:
Родитель
254592cb50
Коммит
a37e0d8fe3
|
@ -13,6 +13,7 @@ TREEHYDRA_MODULES = \
|
|||
$(topsrcdir)/xpcom/analysis/outparams.js \
|
||||
$(topsrcdir)/xpcom/analysis/stack.js \
|
||||
$(topsrcdir)/xpcom/analysis/flow.js \
|
||||
$(topsrcdir)/xpcom/analysis/static-init.js \
|
||||
$(topsrcdir)/js/src/jsstack.js \
|
||||
$(topsrcdir)/layout/generic/frame-verify.js \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Detects static initializers i.e. functions called during static initialization.
|
||||
*/
|
||||
|
||||
require({ after_gcc_pass: "cfg" });
|
||||
|
||||
function process_tree(fn) {
|
||||
for each (let attr in translate_attributes(DECL_ATTRIBUTES(fn)))
|
||||
if (attr.name == "constructor")
|
||||
warning(pretty_func(fn) + " marked with constructor attribute\n");
|
||||
|
||||
if (decl_name_string(fn) != "__static_initialization_and_destruction_0")
|
||||
return;
|
||||
|
||||
let cfg = function_decl_cfg(fn);
|
||||
for (let isn in cfg_isn_iterator(cfg)) {
|
||||
if (isn.tree_code() != GIMPLE_CALL)
|
||||
continue;
|
||||
let decl = gimple_call_fndecl(isn);
|
||||
let lhs = gimple_call_lhs(isn);
|
||||
if (lhs) {
|
||||
warning(pretty_var(lhs) + " defined by call to " + pretty_func(decl) +
|
||||
" during static initialization", location_of(lhs));
|
||||
} else {
|
||||
let arg = constructorArg(isn);
|
||||
if (arg)
|
||||
warning(pretty_var(arg) + " defined by call to constructor " + pretty_func(decl) +
|
||||
" during static initialization", location_of(arg));
|
||||
else
|
||||
warning(pretty_func(decl) + " called during static initialization", location_of(decl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function constructorArg(call) {
|
||||
let decl = gimple_call_fndecl(call);
|
||||
|
||||
if (!DECL_CONSTRUCTOR_P(decl))
|
||||
return null;
|
||||
|
||||
let arg = gimple_call_arg_iterator(call).next();
|
||||
if (TYPE_MAIN_VARIANT(TREE_TYPE(TREE_TYPE(arg))) != DECL_CONTEXT(decl))
|
||||
throw new Error("malformed constructor call?!");
|
||||
|
||||
return arg.tree_code() == ADDR_EXPR ? TREE_OPERAND(arg, 0) : arg;
|
||||
}
|
||||
|
||||
function pretty_func(fn) {
|
||||
return rfunc_string(rectify_function_decl(fn));
|
||||
}
|
||||
|
||||
function pretty_var(v) {
|
||||
return type_string(TREE_TYPE(v)) + " " + decl_name_string(v);
|
||||
}
|
|
@ -137,6 +137,17 @@ OVERRIDE_FAILURE_TESTCASES = \
|
|||
override-virtual.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_INIT_PASS_TESTCASES = \
|
||||
TestStaticInitStructOK.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_INIT_WARNING_TESTCASES = \
|
||||
TestStaticInitAttr.cpp \
|
||||
TestStaticInitConstructor.cpp \
|
||||
TestStaticInitGlobal.cpp \
|
||||
TestStaticInitGlobalConst.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_FAILURE_TESTCASES = \
|
||||
$(FINAL_FAILURE_TESTCASES) \
|
||||
$(FLOW_FAILURE_TESTCASES) \
|
||||
|
@ -147,6 +158,7 @@ STATIC_FAILURE_TESTCASES = \
|
|||
STATIC_WARNING_TESTCASES = \
|
||||
$(OUTPARAMS_WARNING_TESTCASES) \
|
||||
$(STACK_FAILURE_TESTCASES) \
|
||||
$(STATIC_INIT_WARNING_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
STATIC_PASS_TESTCASES = \
|
||||
|
@ -156,6 +168,7 @@ STATIC_PASS_TESTCASES = \
|
|||
$(FLOW_PASS_TESTCASES) \
|
||||
$(MUST_OVERRIDE_PASS_TESTCASES) \
|
||||
$(OVERRIDE_PASS_TESTCASES) \
|
||||
$(STATIC_INIT_PASS_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
int foo() __attribute__((constructor));
|
||||
|
||||
int foo() {
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
struct Blah {
|
||||
public:
|
||||
Blah() { }
|
||||
~Blah() { } // raises call to __cxa_atexit
|
||||
};
|
||||
|
||||
Blah b;
|
|
@ -0,0 +1,5 @@
|
|||
int foo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x = foo();
|
|
@ -0,0 +1,5 @@
|
|||
int foo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const static int x = foo();
|
|
@ -0,0 +1,5 @@
|
|||
struct Blah {
|
||||
int i;
|
||||
};
|
||||
|
||||
Blah b = { 3 };
|
Загрузка…
Ссылка в новой задаче