@@ -678,7 +678,7 @@ new_function (location *loc,
678678 if (is_indirect_return)
679679 {
680680 func_return_type = build_variant_type_copy (func_return_type);
681- TREE_ADDRESSABLE (func_return_type) = 1 ;
681+ // TREE_ADDRESSABLE (func_return_type) = 1;
682682 }
683683
684684 tree *arg_types = (tree *)xcalloc (params->length (), sizeof (tree*));
@@ -703,6 +703,13 @@ new_function (location *loc,
703703
704704 tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL,
705705 NULL_TREE, func_return_type);
706+ if (is_indirect_return)
707+ {
708+ fprintf (stderr, " Indirect return\n " );
709+ DECL_BY_REFERENCE (resdecl) = 1 ;
710+ TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl));
711+ relayout_decl (resdecl);
712+ }
706713 DECL_ARTIFICIAL (resdecl) = 1 ;
707714 DECL_IGNORED_P (resdecl) = 1 ;
708715 DECL_RESULT (fndecl) = resdecl;
@@ -820,7 +827,7 @@ new_function (location *loc,
820827 }
821828
822829 decl_attributes (&fndecl, fn_attributes, 0 );
823- function *func = new function (this , fndecl, kind);
830+ function *func = new function (this , fndecl, kind, is_indirect_return );
824831 m_functions.safe_push (func);
825832 return func;
826833}
@@ -2271,12 +2278,14 @@ operator new (size_t sz)
22712278playback::function::
22722279function (context *ctxt,
22732280 tree fndecl,
2274- enum gcc_jit_function_kind kind)
2281+ enum gcc_jit_function_kind kind,
2282+ bool is_indirect_return)
22752283: m_ctxt(ctxt),
22762284 m_inner_fndecl (fndecl),
22772285 m_inner_bind_expr (NULL ),
22782286 m_kind (kind),
2279- m_blocks ()
2287+ m_blocks (),
2288+ m_has_indirect_return (is_indirect_return)
22802289{
22812290 if (m_kind != GCC_JIT_FUNCTION_IMPORTED)
22822291 {
@@ -2740,14 +2749,28 @@ add_return (location *loc,
27402749 {
27412750 tree t_lvalue = DECL_RESULT (m_func->as_fndecl ());
27422751 tree t_rvalue = rvalue->as_tree ();
2743- if (TREE_TYPE (t_rvalue) != TREE_TYPE (t_lvalue))
2744- t_rvalue = build1 (CONVERT_EXPR,
2745- TREE_TYPE (t_lvalue),
2746- t_rvalue);
2747- modify_retval = build2 (MODIFY_EXPR, return_type,
2748- t_lvalue, t_rvalue);
2749- if (loc)
2750- set_tree_location (modify_retval, loc);
2752+ if (m_func->m_has_indirect_return )
2753+ {
2754+ tree type = TREE_TYPE (TREE_TYPE (t_lvalue));
2755+ tree datum = fold_build1 (INDIRECT_REF, type, t_lvalue);
2756+ tree stmt =
2757+ build2 (MODIFY_EXPR, type,
2758+ datum, t_rvalue);
2759+ if (loc)
2760+ set_tree_location (stmt, loc);
2761+ add_stmt (stmt);
2762+ }
2763+ else
2764+ {
2765+ if (TREE_TYPE (t_rvalue) != TREE_TYPE (t_lvalue))
2766+ t_rvalue = build1 (CONVERT_EXPR,
2767+ TREE_TYPE (t_lvalue),
2768+ t_rvalue);
2769+ modify_retval = build2 (MODIFY_EXPR, return_type,
2770+ t_lvalue, t_rvalue);
2771+ if (loc)
2772+ set_tree_location (modify_retval, loc);
2773+ }
27512774 }
27522775 tree return_stmt = build1 (RETURN_EXPR, return_type,
27532776 modify_retval);
0 commit comments