diff options
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/gigi.h | 11 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 39 |
2 files changed, 39 insertions, 11 deletions
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 36966f9..67a7a47 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -57,12 +57,19 @@ extern void rest_of_type_decl_compilation (tree t); /* Start a new statement group chained to the previous group. */ extern void start_stmt_group (void); -/* Add GNU_STMT to the current BLOCK_STMT node. */ +/* Add GNU_STMT to the current statement group. If it is an expression with + no effects, it is ignored. */ extern void add_stmt (tree gnu_stmt); -/* Similar, but set the location of GNU_STMT to that of GNAT_NODE. */ +/* Similar, but the statement is always added, regardless of side-effects. */ +extern void add_stmt_force (tree gnu_stmt); + +/* Like add_stmt, but set the location of GNU_STMT to that of GNAT_NODE. */ extern void add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node); +/* Similar, but the statement is always added, regardless of side-effects. */ +extern void add_stmt_with_node_force (tree gnu_stmt, Node_Id gnat_node); + /* Return code corresponding to the current code group. It is normally a STATEMENT_LIST, but may also be a BIND_EXPR or TRY_FINALLY_EXPR if BLOCK or cleanups were set. */ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 39dc028..e0d1793 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1739,12 +1739,13 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) /* Cache the expression we have just computed. Since we want to do it at run time, we force the use of a SAVE_EXPR and let the gimplifier - create the temporary. */ + create the temporary in the outermost binding level. We will make + sure in Subprogram_Body_to_gnu that it is evaluated on all possible + paths by forcing its evaluation on entry of the function. */ if (pa) { gnu_result = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result); - TREE_SIDE_EFFECTS (gnu_result) = 1; if (attribute == Attr_First) pa->first = gnu_result; else if (attribute == Attr_Last) @@ -2634,8 +2635,9 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) VEC_pop (tree, gnu_return_label_stack); - /* If we populated the parameter attributes cache, we need to make sure - that the cached expressions are evaluated on all possible paths. */ + /* If we populated the parameter attributes cache, we need to make sure that + the cached expressions are evaluated on all the possible paths leading to + their uses. So we force their evaluation on entry of the function. */ cache = DECL_STRUCT_FUNCTION (gnu_subprog_decl)->language->parm_attr_cache; if (cache) { @@ -2647,11 +2649,11 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) FOR_EACH_VEC_ELT (parm_attr, cache, i, pa) { if (pa->first) - add_stmt_with_node (pa->first, gnat_node); + add_stmt_with_node_force (pa->first, gnat_node); if (pa->last) - add_stmt_with_node (pa->last, gnat_node); + add_stmt_with_node_force (pa->last, gnat_node); if (pa->length) - add_stmt_with_node (pa->length, gnat_node); + add_stmt_with_node_force (pa->length, gnat_node); } add_stmt (gnu_result); @@ -5969,7 +5971,8 @@ start_stmt_group (void) current_stmt_group = group; } -/* Add GNU_STMT to the current statement group. */ +/* Add GNU_STMT to the current statement group. If it is an expression with + no effects, it is ignored. */ void add_stmt (tree gnu_stmt) @@ -5977,7 +5980,15 @@ add_stmt (tree gnu_stmt) append_to_statement_list (gnu_stmt, ¤t_stmt_group->stmt_list); } -/* Similar, but set the location of GNU_STMT to that of GNAT_NODE. */ +/* Similar, but the statement is always added, regardless of side-effects. */ + +void +add_stmt_force (tree gnu_stmt) +{ + append_to_statement_list_force (gnu_stmt, ¤t_stmt_group->stmt_list); +} + +/* Like add_stmt, but set the location of GNU_STMT to that of GNAT_NODE. */ void add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node) @@ -5987,6 +5998,16 @@ add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node) add_stmt (gnu_stmt); } +/* Similar, but the statement is always added, regardless of side-effects. */ + +void +add_stmt_with_node_force (tree gnu_stmt, Node_Id gnat_node) +{ + if (Present (gnat_node)) + set_expr_location_from_node (gnu_stmt, gnat_node); + add_stmt_force (gnu_stmt); +} + /* Add a declaration statement for GNU_DECL to the current statement group. Get SLOC from Entity_Id. */ |