* 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).