public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* ADDR_EXPR and temporaries
@ 2013-12-30 13:12 Jan Trávníček
  2014-01-01 20:53 ` Jan Trávníček
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Trávníček @ 2013-12-30 13:12 UTC (permalink / raw)
  To: gcc-help

Hi all,

   I have been trying to understand how to write front end for gcc by 
directly creating something in parse_file function. However I have a 
problem with ADDR_EXPR.
I'm working with gcc 4.9.0 20131223 experimental (available from svn).

Consider the following code: 
 >>>---------------------------------------------------------------------
   tree params = NULL_TREE;

   tree main_fn_type = build_function_type_list(integer_type_node, params);
   tree main_fn_decl = build_decl(BUILTINS_LOCATION, FUNCTION_DECL, 
get_identifier("main"), main_fn_type);

   DECL_CONTEXT(main_fn_decl) = NULL_TREE;
   TREE_STATIC(main_fn_decl) = true;
   TREE_PUBLIC(main_fn_decl) = true;
   DECL_ARGUMENTS(main_fn_decl) = NULL_TREE;

   tree main_ret = build_decl(BUILTINS_LOCATION, RESULT_DECL, NULL_TREE, 
TREE_TYPE(main_fn_type));
   DECL_CONTEXT(main_ret) = main_fn_decl;
   DECL_ARTIFICIAL(main_ret) = true;
   DECL_IGNORED_P(main_ret) = true;

   DECL_RESULT(main_fn_decl) = main_ret;

   tree main_stmts = alloc_stmt_list ();
   tree main_block_decls = NULL_TREE;

   /* Declare a variables */
   tree variable_i = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("i"), integer_type_node);
   DECL_CONTEXT(variable_i) = main_fn_decl;

   tree variable_j = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("j"), integer_type_node);
   DECL_CONTEXT(variable_j) = main_fn_decl;

   tree variable_pi = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("pi"), build_pointer_type(integer_type_node));
   DECL_CONTEXT(variable_pi) = main_fn_decl;

   tree variable_pj = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("pj"), build_pointer_type(integer_type_node));
   DECL_CONTEXT(variable_pj) = main_fn_decl;

   TREE_CHAIN( variable_pj ) = main_block_decls;
   main_block_decls = variable_pj;

   TREE_CHAIN( variable_pi ) = main_block_decls;
   main_block_decls = variable_pi;

   TREE_CHAIN( variable_j ) = main_block_decls;
   main_block_decls = variable_j;

   TREE_CHAIN( variable_i ) = main_block_decls;
   main_block_decls = variable_i;

   /* Set variables */
   tree set_pi = build2(INIT_EXPR, TREE_TYPE(variable_pi), variable_pi, 
build1(ADDR_EXPR, TREE_TYPE(variable_pi), variable_i));
   TREE_USED(set_pi) = true;
   DECL_INITIAL(variable_pi) = set_pi;

   tree set_pj = build2(MODIFY_EXPR, TREE_TYPE(variable_pj), 
variable_pj, build1(ADDR_EXPR, TREE_TYPE(variable_pj), variable_j));
   TREE_USED(set_pj) = true;
   append_to_statement_list(set_pj, &main_stmts);

   /* Set return and return */
   tree main_set_ret = build2(MODIFY_EXPR, TREE_TYPE(main_ret),
                  main_ret, build_int_cst(integer_type_node, 10));
   TREE_USED(main_set_ret) = true;
   tree main_ret_expr = build1(RETURN_EXPR, void_type_node, main_set_ret);
   append_to_statement_list(main_ret_expr, &main_stmts);

   /* Create main block */
   tree main_block = build_block(main_block_decls, NULL_TREE, 
main_fn_decl, NULL_TREE);

   DECL_INITIAL(main_fn_decl) = main_block;
   TREE_USED(main_block) = true;

   tree bind = build3( BIND_EXPR, void_type_node, 
BLOCK_VARS(main_block), NULL_TREE, main_block );

   /* Finalize the main function */
   BIND_EXPR_BODY(bind) = main_stmts;
   DECL_SAVED_TREE(main_fn_decl) = bind;
   TREE_SIDE_EFFECTS(bind) = true;

   debug_body(main_fn_decl);

   vec_safe_push( global_decls_vec, main_fn_decl );

   /* Prepare the function for the GCC middle-end */
   gimplify_function_tree(main_fn_decl);
   cgraph_finalize_function(main_fn_decl, false);

   debug_body(main_fn_decl);
<<<---------------------------------------------------------------------

then the debug_body functions print the following:
 >>>---------------------------------------------------------------------
(nofn) ()
{
   signed int i;
   signed int j;
   signed int * pi = pi = &i;
   signed int * pj;

   pj = &j;
   return 10;
}

main ()
{
   signed int j.0;
   signed int D.30;
   signed int i;
   signed int j;
   signed int * pi = pi = &i;
   signed int * pj;

   j.0 = j;
   pj = &j.0;
   D.30 = 10;
   return D.30;
}
<<<---------------------------------------------------------------------

Strange thing is why there is pi = pi in signed int * pi = pi = &i; but 
it is ok from the semantics point of view.
And more important is why there is temporary j.0 after gimplification 
and pj is made to point at this temporary:
j.0 = j;
pj = &j.0;

I read that ADDR_EXPR can introduces a temporary when the argument is 
not lvalue. But this is not the case.

This example is simplified example of what I have been trying to do: 
Call scanf with agruments "%d" and &j. The fromating string is passed 
correctly (tested with printf), however the second argument is made a 
pointer to a temporary so it does not work.

Thank you for your reply.

Best regards,
Jan Tråvníèek

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: ADDR_EXPR and temporaries
  2013-12-30 13:12 ADDR_EXPR and temporaries Jan Trávníček
@ 2014-01-01 20:53 ` Jan Trávníček
  0 siblings, 0 replies; 2+ messages in thread
From: Jan Trávníček @ 2014-01-01 20:53 UTC (permalink / raw)
  To: gcc-help

Hi,

   so I solved it, apparently my code missed TREE_ADDRESSABLE in 
variable declaration:

   tree variable_j = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("j"), integer_type_node);
   TREE_ADDRESSABLE(variable_j) = true;
   DECL_CONTEXT(variable_j) = main_fn_decl;

   and DECL_INITIAL is used a bit differently:

   tree set_pi = build1(ADDR_EXPR, 
build_pointer_type(TREE_TYPE(variable_i)), variable_i);
   TREE_USED(set_pi) = true;
   DECL_INITIAL(variable_pi) = set_pi;

Regards,
Jan Tråvníèek

On 12/30/2013 02:11 PM, Jan Tråvníèek wrote:
> Hi all,
>
>   I have been trying to understand how to write front end for gcc by 
> directly creating something in parse_file function. However I have a 
> problem with ADDR_EXPR.
> I'm working with gcc 4.9.0 20131223 experimental (available from svn).
>
> Consider the following code: 
> >>>---------------------------------------------------------------------
>   tree params = NULL_TREE;
>
>   tree main_fn_type = build_function_type_list(integer_type_node, 
> params);
>   tree main_fn_decl = build_decl(BUILTINS_LOCATION, FUNCTION_DECL, 
> get_identifier("main"), main_fn_type);
>
>   DECL_CONTEXT(main_fn_decl) = NULL_TREE;
>   TREE_STATIC(main_fn_decl) = true;
>   TREE_PUBLIC(main_fn_decl) = true;
>   DECL_ARGUMENTS(main_fn_decl) = NULL_TREE;
>
>   tree main_ret = build_decl(BUILTINS_LOCATION, RESULT_DECL, 
> NULL_TREE, TREE_TYPE(main_fn_type));
>   DECL_CONTEXT(main_ret) = main_fn_decl;
>   DECL_ARTIFICIAL(main_ret) = true;
>   DECL_IGNORED_P(main_ret) = true;
>
>   DECL_RESULT(main_fn_decl) = main_ret;
>
>   tree main_stmts = alloc_stmt_list ();
>   tree main_block_decls = NULL_TREE;
>
>   /* Declare a variables */
>   tree variable_i = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
> get_identifier("i"), integer_type_node);
>   DECL_CONTEXT(variable_i) = main_fn_decl;
>
>   tree variable_j = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
> get_identifier("j"), integer_type_node);
>   DECL_CONTEXT(variable_j) = main_fn_decl;
>
>   tree variable_pi = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
> get_identifier("pi"), build_pointer_type(integer_type_node));
>   DECL_CONTEXT(variable_pi) = main_fn_decl;
>
>   tree variable_pj = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
> get_identifier("pj"), build_pointer_type(integer_type_node));
>   DECL_CONTEXT(variable_pj) = main_fn_decl;
>
>   TREE_CHAIN( variable_pj ) = main_block_decls;
>   main_block_decls = variable_pj;
>
>   TREE_CHAIN( variable_pi ) = main_block_decls;
>   main_block_decls = variable_pi;
>
>   TREE_CHAIN( variable_j ) = main_block_decls;
>   main_block_decls = variable_j;
>
>   TREE_CHAIN( variable_i ) = main_block_decls;
>   main_block_decls = variable_i;
>
>   /* Set variables */
>   tree set_pi = build2(INIT_EXPR, TREE_TYPE(variable_pi), variable_pi, 
> build1(ADDR_EXPR, TREE_TYPE(variable_pi), variable_i));
>   TREE_USED(set_pi) = true;
>   DECL_INITIAL(variable_pi) = set_pi;
>
>   tree set_pj = build2(MODIFY_EXPR, TREE_TYPE(variable_pj), 
> variable_pj, build1(ADDR_EXPR, TREE_TYPE(variable_pj), variable_j));
>   TREE_USED(set_pj) = true;
>   append_to_statement_list(set_pj, &main_stmts);
>
>   /* Set return and return */
>   tree main_set_ret = build2(MODIFY_EXPR, TREE_TYPE(main_ret),
>                  main_ret, build_int_cst(integer_type_node, 10));
>   TREE_USED(main_set_ret) = true;
>   tree main_ret_expr = build1(RETURN_EXPR, void_type_node, main_set_ret);
>   append_to_statement_list(main_ret_expr, &main_stmts);
>
>   /* Create main block */
>   tree main_block = build_block(main_block_decls, NULL_TREE, 
> main_fn_decl, NULL_TREE);
>
>   DECL_INITIAL(main_fn_decl) = main_block;
>   TREE_USED(main_block) = true;
>
>   tree bind = build3( BIND_EXPR, void_type_node, 
> BLOCK_VARS(main_block), NULL_TREE, main_block );
>
>   /* Finalize the main function */
>   BIND_EXPR_BODY(bind) = main_stmts;
>   DECL_SAVED_TREE(main_fn_decl) = bind;
>   TREE_SIDE_EFFECTS(bind) = true;
>
>   debug_body(main_fn_decl);
>
>   vec_safe_push( global_decls_vec, main_fn_decl );
>
>   /* Prepare the function for the GCC middle-end */
>   gimplify_function_tree(main_fn_decl);
>   cgraph_finalize_function(main_fn_decl, false);
>
>   debug_body(main_fn_decl);
> <<<---------------------------------------------------------------------
>
> then the debug_body functions print the following:
> >>>---------------------------------------------------------------------
> (nofn) ()
> {
>   signed int i;
>   signed int j;
>   signed int * pi = pi = &i;
>   signed int * pj;
>
>   pj = &j;
>   return 10;
> }
>
> main ()
> {
>   signed int j.0;
>   signed int D.30;
>   signed int i;
>   signed int j;
>   signed int * pi = pi = &i;
>   signed int * pj;
>
>   j.0 = j;
>   pj = &j.0;
>   D.30 = 10;
>   return D.30;
> }
> <<<---------------------------------------------------------------------
>
> Strange thing is why there is pi = pi in signed int * pi = pi = &i; 
> but it is ok from the semantics point of view.
> And more important is why there is temporary j.0 after gimplification 
> and pj is made to point at this temporary:
> j.0 = j;
> pj = &j.0;
>
> I read that ADDR_EXPR can introduces a temporary when the argument is 
> not lvalue. But this is not the case.
>
> This example is simplified example of what I have been trying to do: 
> Call scanf with agruments "%d" and &j. The fromating string is passed 
> correctly (tested with printf), however the second argument is made a 
> pointer to a temporary so it does not work.
>
> Thank you for your reply.
>
> Best regards,
> Jan Tråvníèek

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-01-01 20:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-30 13:12 ADDR_EXPR and temporaries Jan Trávníček
2014-01-01 20:53 ` Jan Trávníček

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).