diff options
author | Bin Cheng <bin.cheng@arm.com> | 2016-02-01 17:17:47 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2016-02-01 17:17:47 +0000 |
commit | e681fb2b5324bf266bd9caedceb2f84792207de6 (patch) | |
tree | 71a5ad91eb43ad0ae0479f0aeb90f06e0084d1e5 /gcc/fold-const.c | |
parent | b6adbb9faabb776ae7b70a5f5943ae883b1f76ea (diff) | |
download | gcc-e681fb2b5324bf266bd9caedceb2f84792207de6.zip gcc-e681fb2b5324bf266bd9caedceb2f84792207de6.tar.gz gcc-e681fb2b5324bf266bd9caedceb2f84792207de6.tar.bz2 |
re PR tree-optimization/67921 ("internal compiler error: in build_polynomial_chrec, at tree-chrec.h:147" when using -fsanitize=undefined)
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.
From-SVN: r233042
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index bece8d7..e34bc81 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) |