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_TREE, NULL_TREE, NULL_TREE );
  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;
}


Reply via email to