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
This commit is contained in:
Bin Cheng 2016-02-01 17:17:47 +00:00 committed by Bin Cheng
parent b6adbb9faa
commit e681fb2b53
4 changed files with 56 additions and 8 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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]);
}
}