diff options
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 7031bfb..36a2462 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -989,6 +989,10 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) tree renamed_obj; if (TREE_CODE (gnu_result) == PARM_DECL + && DECL_BY_DOUBLE_REF_P (gnu_result)) + gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result); + + if (TREE_CODE (gnu_result) == PARM_DECL && DECL_BY_COMPONENT_PTR_P (gnu_result)) gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, @@ -2595,9 +2599,13 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) gnat_param = Next_Formal_With_Extras (gnat_param)) { tree gnu_param = get_gnu_tree (gnat_param); + bool is_var_decl = (TREE_CODE (gnu_param) == VAR_DECL); + annotate_object (gnat_param, TREE_TYPE (gnu_param), NULL_TREE, - DECL_BY_REF_P (gnu_param)); - if (TREE_CODE (gnu_param) == VAR_DECL) + DECL_BY_REF_P (gnu_param), + !is_var_decl && DECL_BY_DOUBLE_REF_P (gnu_param)); + + if (is_var_decl) save_gnu_tree (gnat_param, NULL_TREE, false); } @@ -2900,6 +2908,12 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) /* The symmetry of the paths to the type of an entity is broken here since arguments don't know that they will be passed by ref. */ gnu_formal_type = TREE_TYPE (get_gnu_tree (gnat_formal)); + + if (DECL_BY_DOUBLE_REF_P (gnu_formal)) + gnu_actual + = build_unary_op (ADDR_EXPR, TREE_TYPE (gnu_formal_type), + gnu_actual); + gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual); } else if (gnu_formal |