aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-02-01 17:17:47 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-02-01 17:17:47 +0000
commite681fb2b5324bf266bd9caedceb2f84792207de6 (patch)
tree71a5ad91eb43ad0ae0479f0aeb90f06e0084d1e5 /gcc/fold-const.c
parentb6adbb9faabb776ae7b70a5f5943ae883b1f76ea (diff)
downloadgcc-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.c29
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)