aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-array-notation.c
diff options
context:
space:
mode:
authorBalaji V. Iyer <balaji.v.iyer@intel.com>2014-01-23 17:00:53 +0000
committerBalaji V. Iyer <bviyer@gcc.gnu.org>2014-01-23 09:00:53 -0800
commit40f14e9f103d3bcd1216304919b568dd48e471bc (patch)
tree5169513707a6f8d8bcc95326cc2a05ff5acac171 /gcc/c/c-array-notation.c
parentc733429f54ace8a10f50c2a751a0c2c940b8c9ce (diff)
downloadgcc-40f14e9f103d3bcd1216304919b568dd48e471bc.zip
gcc-40f14e9f103d3bcd1216304919b568dd48e471bc.tar.gz
gcc-40f14e9f103d3bcd1216304919b568dd48e471bc.tar.bz2
re PR c/59825 (Many cilkplus test failures)
Fix for PR c/59825. 2014-01-23 Balaji V. Iyer <balaji.v.iyer@intel.com> PR c/59825 * c-array-notation.c (expand_array_notation_exprs): Rewrote this function to use walk_tree and moved a lot of its functionality to expand_array_notations. (expand_array_notations): New function. From-SVN: r206991
Diffstat (limited to 'gcc/c/c-array-notation.c')
-rw-r--r--gcc/c/c-array-notation.c105
1 files changed, 53 insertions, 52 deletions
diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
index 5526ee9..6a5631c 100644
--- a/gcc/c/c-array-notation.c
+++ b/gcc/c/c-array-notation.c
@@ -1218,22 +1218,21 @@ fix_return_expr (tree expr)
return new_mod_list;
}
-/* Walks through tree node T and find all the call-statements that do not return
- anything and fix up any array notations they may carry. The return value
- is the same type as T but with all array notations replaced with appropriate
- STATEMENT_LISTS. */
+/* Callback for walk_tree. Expands all array notations in *TP. *WALK_SUBTREES
+ is set to 1 unless *TP contains no array notation expressions. */
-tree
-expand_array_notation_exprs (tree t)
+static tree
+expand_array_notations (tree *tp, int *walk_subtrees, void *)
{
- if (!contains_array_notation_expr (t))
- return t;
+ if (!contains_array_notation_expr (*tp))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ *walk_subtrees = 1;
- switch (TREE_CODE (t))
+ switch (TREE_CODE (*tp))
{
- case BIND_EXPR:
- t = expand_array_notation_exprs (BIND_EXPR_BODY (t));
- return t;
case TRUTH_ORIF_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_OR_EXPR:
@@ -1241,61 +1240,63 @@ expand_array_notation_exprs (tree t)
case TRUTH_XOR_EXPR:
case TRUTH_NOT_EXPR:
case COND_EXPR:
- t = fix_conditional_array_notations (t);
-
- /* After the expansion if they are still a COND_EXPR, we go into its
- subtrees. */
- if (TREE_CODE (t) == COND_EXPR)
- {
- if (COND_EXPR_THEN (t))
- COND_EXPR_THEN (t) =
- expand_array_notation_exprs (COND_EXPR_THEN (t));
- if (COND_EXPR_ELSE (t))
- COND_EXPR_ELSE (t) =
- expand_array_notation_exprs (COND_EXPR_ELSE (t));
- }
- return t;
- case STATEMENT_LIST:
- {
- tree_stmt_iterator ii_tsi;
- for (ii_tsi = tsi_start (t); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi))
- *tsi_stmt_ptr (ii_tsi) =
- expand_array_notation_exprs (*tsi_stmt_ptr (ii_tsi));
- }
- return t;
+ *tp = fix_conditional_array_notations (*tp);
+ break;
case MODIFY_EXPR:
{
- location_t loc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) :
+ location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) :
UNKNOWN_LOCATION;
- tree lhs = TREE_OPERAND (t, 0);
- tree rhs = TREE_OPERAND (t, 1);
+ tree lhs = TREE_OPERAND (*tp, 0);
+ tree rhs = TREE_OPERAND (*tp, 1);
location_t rhs_loc = EXPR_HAS_LOCATION (rhs) ? EXPR_LOCATION (rhs) :
UNKNOWN_LOCATION;
- t = build_array_notation_expr (loc, lhs, TREE_TYPE (lhs), NOP_EXPR,
- rhs_loc, rhs, TREE_TYPE (rhs));
- return t;
+ *tp = build_array_notation_expr (loc, lhs, TREE_TYPE (lhs), NOP_EXPR,
+ rhs_loc, rhs, TREE_TYPE (rhs));
}
+ break;
case CALL_EXPR:
- t = fix_array_notation_call_expr (t);
- return t;
+ *tp = fix_array_notation_call_expr (*tp);
+ break;
case RETURN_EXPR:
- if (contains_array_notation_expr (t))
- t = fix_return_expr (t);
- return t;
+ *tp = fix_return_expr (*tp);
+ break;
+ case COMPOUND_EXPR:
+ if (TREE_CODE (TREE_OPERAND (*tp, 0)) == SAVE_EXPR)
+ {
+ /* In here we are calling expand_array_notations because
+ we need to be able to catch the return value and check if
+ it is an error_mark_node. */
+ expand_array_notations (&TREE_OPERAND (*tp, 1), walk_subtrees, NULL);
+
+ /* SAVE_EXPR cannot have an error_mark_node inside it. This check
+ will make sure that if there is an error in expanding of
+ array notations (e.g. rank mismatch) then replace the entire
+ SAVE_EXPR with an error_mark_node. */
+ if (TREE_OPERAND (*tp, 1) == error_mark_node)
+ *tp = error_mark_node;
+ }
+ break;
case ARRAY_NOTATION_REF:
- /* IF we are here, then we are dealing with cases like this:
+ /* If we are here, then we are dealing with cases like this:
A[:];
A[x:y:z];
A[x:y];
Replace those with just void zero node. */
- t = void_zero_node;
+ *tp = void_zero_node;
default:
- for (int ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (t)); ii++)
- if (contains_array_notation_expr (TREE_OPERAND (t, ii)))
- TREE_OPERAND (t, ii) =
- expand_array_notation_exprs (TREE_OPERAND (t, ii));
- return t;
+ break;
}
+ return NULL_TREE;
+}
+
+/* Walks through tree node T and expands all array notations in its subtrees.
+ The return value is the same type as T but with all array notations
+ replaced with appropriate ARRAY_REFS with a loop around it. */
+
+tree
+expand_array_notation_exprs (tree t)
+{
+ walk_tree (&t, expand_array_notations, NULL, NULL);
return t;
}