diff options
author | Bin Cheng <bin.cheng@arm.com> | 2016-02-01 17:17:47 +0000 |
---|---|---|
committer | Bin Cheng <bin.cheng@arm.com> | 2016-02-01 17:17:47 +0000 |
commit | 4abcbb77ecd0f968495636f6f04d5771069518c9 (patch) | |
tree | 71a5ad91eb43ad0ae0479f0aeb90f06e0084d1e5 | |
parent | 5e77a28ef37eb26a6c1d0023d930ebccc4a8f579 (diff) |
PR tree-optimization/67921
* fold-const.c (split_tree): New parameters. Convert pointer
type variable part to proper type before negating.
(fold_binary_loc): Pass new arguments to split_tree.
gcc/testsuite/ChangeLog
PR tree-optimization/67921
* c-c++-common/ubsan/pr67921.c: New test.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@233042 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/pr67921.c | 23 |
4 files changed, 56 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb6d8bdfc64..ba4deed7a24 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-02-01 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/67921 + * fold-const.c (split_tree): New parameters. Convert pointer + type variable part to proper type before negating. + (fold_binary_loc): Pass new arguments to split_tree. + 2016-02-01 Nathan Sidwell <nathan@codesourcery.com> * config/nvptx/nvptx.c (PTX_GANG_DEFAULT): New. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index bece8d74b46..e34bc81eae8 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -109,7 +109,8 @@ enum comparison_code { static bool negate_expr_p (tree); static tree negate_expr (tree); -static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int); +static tree split_tree (location_t, tree, tree, enum tree_code, + tree *, tree *, tree *, int); static tree associate_trees (location_t, tree, tree, enum tree_code, tree); static enum comparison_code comparison_to_compcode (enum tree_code); static enum tree_code compcode_to_comparison (enum comparison_code); @@ -767,7 +768,10 @@ negate_expr (tree t) literal for which we use *MINUS_LITP instead. If NEGATE_P is true, we are negating all of IN, again except a literal - for which we use *MINUS_LITP instead. + for which we use *MINUS_LITP instead. If a variable part is of pointer + type, it is negated after converting to TYPE. This prevents us from + generating illegal MINUS pointer expression. LOC is the location of + the converted variable part. If IN is itself a literal or constant, return it as appropriate. @@ -775,8 +779,8 @@ negate_expr (tree t) same type as IN, but they will have the same signedness and mode. */ static tree -split_tree (tree in, enum tree_code code, tree *conp, tree *litp, - tree *minus_litp, int negate_p) +split_tree (location_t loc, tree in, tree type, enum tree_code code, + tree *conp, tree *litp, tree *minus_litp, int negate_p) { tree var = 0; @@ -833,7 +837,12 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp, if (neg_conp_p) *conp = negate_expr (*conp); if (neg_var_p) - var = negate_expr (var); + { + /* Convert to TYPE before negating a pointer type expr. */ + if (var && POINTER_TYPE_P (TREE_TYPE (var))) + var = fold_convert_loc (loc, type, var); + var = negate_expr (var); + } } else if (TREE_CODE (in) == BIT_NOT_EXPR && code == PLUS_EXPR) @@ -854,6 +863,9 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp, else if (*minus_litp) *litp = *minus_litp, *minus_litp = 0; *conp = negate_expr (*conp); + /* Convert to TYPE before negating a pointer type expr. */ + if (var && POINTER_TYPE_P (TREE_TYPE (var))) + var = fold_convert_loc (loc, type, var); var = negate_expr (var); } @@ -9621,9 +9633,10 @@ fold_binary_loc (location_t loc, then the result with variables. This increases the chances of literals being recombined later and of generating relocatable expressions for the sum of a constant and literal. */ - var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0); - var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1, - code == MINUS_EXPR); + var0 = split_tree (loc, arg0, type, code, + &con0, &lit0, &minus_lit0, 0); + var1 = split_tree (loc, arg1, type, code, + &con1, &lit1, &minus_lit1, code == MINUS_EXPR); /* Recombine MINUS_EXPR operands by using PLUS_EXPR. */ if (code == MINUS_EXPR) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bfd6e9f6ce4..7efd95cebc0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-01 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/67921 + * c-c++-common/ubsan/pr67921.c: New test. + 2016-02-01 Richard Biener <rguenther@suse.de> PR middle-end/69556 diff --git a/gcc/testsuite/c-c++-common/ubsan/pr67921.c b/gcc/testsuite/c-c++-common/ubsan/pr67921.c new file mode 100644 index 00000000000..728ff93a60f --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr67921.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined" } */ + +struct s +{ + int n; + int arr[][6]; +}; +void bar (int); +void foo (struct s *ptr) +{ + int i; + for (; i < 2; i++) + for (; ptr->n;) + { + int *a = ptr->arr[i]; + int b[66]; + int j = 0; + + for (; j < 56; j++) + bar (a[j] - b[j]); + } +} |