Hi,
I am trying to add a new destructor function to object files I
compile. I'm doing this to instrument programs and then, once the
program has finished I want to print out the statistics I've gathered.
So, just before pass 'remove_useless_stmts' is called on each
function I try to create a static destructor which will print stats for
the current function (and obviously, I don't do it on the functions just
created).
Below I've put a simpler form, which should work for a one function
program. Calling createFnDecl() creates a new function called
__my_new_function. It should print "It worked!" when the program exits.
Now, with compiler flag -O0, this works just fine, but with -O1 or
above it seg faults the compiler.
Can anyone tell me what I'm doing wrong?
Cheers,
Hugh.
static tree createFnBody() {
tree arg;
tree argList;
tree putsFn;
tree call;
tree bind;
char msg[] = "It worked!";
bind = build3( BIND_EXPR, void_type_node, NULL, NULL, NULL );
TREE_SIDE_EFFECTS( bind ) = 1;
putsFn = implicit_built_in_decls[ BUILT_IN_PUTS ];
arg = build_string_literal( sizeof( msg ) + 1, msg );
argList = tree_cons( NULL_TREE, arg, NULL_TREE );
call = build_function_call_expr( putsFn, argList );
append_to_statement_list( call, &BIND_EXPR_BODY( bind ));
return bind;
}
static tree createFnDecl() {
tree callTypes;
tree fnName;
tree fnDecl;
tree t;
struct function* oldCfun = cfun;
fnName = get_identifier( "__my_new_function" );
callTypes = build_function_type_list( void_type_node, NULL_TREE );
fnDecl = build_decl( FUNCTION_DECL, fnName, callTypes );
fnDecl = lang_hooks.decls.pushdecl( fnDecl );
TREE_STATIC( fnDecl ) = 1;
TREE_USED( fnDecl ) = 1;
DECL_ARTIFICIAL( fnDecl ) = 1;
DECL_IGNORED_P( fnDecl ) = 0;
TREE_PUBLIC( fnDecl ) = 0;
DECL_UNINLINABLE( fnDecl ) = 1;
DECL_EXTERNAL( fnDecl ) = 0;
DECL_CONTEXT( fnDecl ) = NULL_TREE;
DECL_INITIAL( fnDecl ) = make_node ( BLOCK );
DECL_STATIC_DESTRUCTOR( fnDecl ) = 1;
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT( fnDecl ) = 1;
t = build_decl( RESULT_DECL, NULL_TREE, void_type_node );
DECL_ARTIFICIAL( t ) = 1;
DECL_IGNORED_P( t ) = 1;
DECL_RESULT( fnDecl ) = t;
DECL_SAVED_TREE( fnDecl ) = createFnBody();
allocate_struct_function( fnDecl );
cgraph_add_new_function( fnDecl );
cfun = oldCfun;
return fnDecl;
}