Hello,

The attached plug-in builds a function like this:

  my_function (void * parm.0)
  {
    __builtin_puts (parm.0);
  }

However, the generated assembly clears the first-argument register
(%edi) before calling ‘puts’, instead of actually passing the parameter:

  my_function:
  .LFB0:
          .file 1 "tt.c"
          .loc 1 1 0
          .cfi_startproc
          .loc 1 1 0
          xorl  %edi, %edi  ;; %edi shouldn’t be cleared
          jmp   puts
          .cfi_endproc

Any idea what I’m doing wrong?

(Please let me know if I should direct such questions elsewhere.)

Thanks,
Ludo’.

int plugin_is_GPL_compatible;

#include <gcc-plugin.h>
#include <plugin-version.h>

#include <plugin.h>
#include <tree.h>
#include <gimple.h>
#include <function.h>
#include <cgraph.h>

static void
define_function (void *gcc_data, void *user_data)
{
  tree decl, void_ptr;
  location_t loc = input_location;

  void_ptr = build_pointer_type (void_type_node);
  decl = build_decl (loc, FUNCTION_DECL, get_identifier ("my_function"),
		     build_function_type_list (void_type_node,
					       void_ptr, NULL_TREE));

  tree parm;
  parm = build_decl (loc, PARM_DECL,
		     create_tmp_var_name ("parm"),
		     void_ptr);

  DECL_CONTEXT (parm) = decl;
  TREE_USED (parm) = true;
  DECL_ARGUMENTS (decl) = parm;

  tree result;
  result = build_decl (loc, RESULT_DECL, NULL_TREE, void_type_node);
  DECL_CONTEXT (result) = decl;
  DECL_ARTIFICIAL (result) = true;
  DECL_IGNORED_P (result) = true;
  DECL_RESULT (decl) = result;

  DECL_INITIAL (decl) =
    build_block (NULL_TREE, NULL_TREE, decl, NULL_TREE);
  DECL_SAVED_TREE (decl) =
    build_call_expr (built_in_decls[BUILT_IN_PUTS], 1, parm);

  TREE_PUBLIC (decl) = true;
  TREE_STATIC (decl) = true;
  TREE_USED (decl) = true;
  DECL_ARTIFICIAL (decl) = true;
  DECL_EXTERNAL (decl) = false;
  DECL_UNINLINABLE (decl) = true;

  set_cfun (NULL);
  current_function_decl = decl;
  allocate_struct_function (decl, false);
  cfun->function_end_locus = loc;

  cgraph_finalize_function (decl, false);
}

int
plugin_init (struct plugin_name_args *plugin_info,
	     struct plugin_gcc_version *version)
{
  if (!plugin_default_version_check (version, &gcc_version))
    return 1;

  register_callback ("the-plugin", PLUGIN_START_UNIT,
		     define_function, NULL);

  return 0;
}

/*
   Local Variables:
   compile-command: "gcc -Wall -g -fPIC -shared -o t.so t.c -I`gcc -print-file-name=plugin`/include"
   End:
 */

Reply via email to