Commit 5a98025d by Jakub Jelinek Committed by Jakub Jelinek

re PR sanitizer/85213 (-fsanitize=undefined internal compiler error: in…

re PR sanitizer/85213 (-fsanitize=undefined internal compiler error: in fold_convert_loc, at fold-const.c:2402)

	PR sanitizer/85213
	* fold-const.c (twoval_comparison_p): Remove SAVE_P argument and don't
	look through SAVE_EXPRs with non-side-effects argument.  Adjust
	recursive calls.
	(fold_comparison): Adjust twoval_comparison_p caller, don't handle
	save_p here.

	* c-c++-common/ubsan/pr85213.c: New test.

From-SVN: r259167
parent 6ca83833
2018-04-06 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/85213
* fold-const.c (twoval_comparison_p): Remove SAVE_P argument and don't
look through SAVE_EXPRs with non-side-effects argument. Adjust
recursive calls.
(fold_comparison): Adjust twoval_comparison_p caller, don't handle
save_p here.
2018-04-06 Richard Biener <rguenther@suse.de> 2018-04-06 Richard Biener <rguenther@suse.de>
PR middle-end/85180 PR middle-end/85180
......
...@@ -115,7 +115,7 @@ static tree negate_expr (tree); ...@@ -115,7 +115,7 @@ static tree negate_expr (tree);
static tree associate_trees (location_t, tree, tree, enum tree_code, tree); static tree associate_trees (location_t, tree, tree, enum tree_code, tree);
static enum comparison_code comparison_to_compcode (enum tree_code); static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code); static enum tree_code compcode_to_comparison (enum comparison_code);
static int twoval_comparison_p (tree, tree *, tree *, int *); static int twoval_comparison_p (tree, tree *, tree *);
static tree eval_subst (location_t, tree, tree, tree, tree, tree); static tree eval_subst (location_t, tree, tree, tree, tree, tree);
static tree optimize_bit_field_compare (location_t, enum tree_code, static tree optimize_bit_field_compare (location_t, enum tree_code,
tree, tree, tree); tree, tree, tree);
...@@ -3549,13 +3549,12 @@ operand_equal_for_comparison_p (tree arg0, tree arg1) ...@@ -3549,13 +3549,12 @@ operand_equal_for_comparison_p (tree arg0, tree arg1)
two different values, which will be stored in *CVAL1 and *CVAL2; if two different values, which will be stored in *CVAL1 and *CVAL2; if
they are nonzero it means that some operands have already been found. they are nonzero it means that some operands have already been found.
No variables may be used anywhere else in the expression except in the No variables may be used anywhere else in the expression except in the
comparisons. If SAVE_P is true it means we removed a SAVE_EXPR around comparisons.
the expression and save_expr needs to be called with CVAL1 and CVAL2.
If this is true, return 1. Otherwise, return zero. */ If this is true, return 1. Otherwise, return zero. */
static int static int
twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p) twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
{ {
enum tree_code code = TREE_CODE (arg); enum tree_code code = TREE_CODE (arg);
enum tree_code_class tclass = TREE_CODE_CLASS (code); enum tree_code_class tclass = TREE_CODE_CLASS (code);
...@@ -3568,39 +3567,23 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p) ...@@ -3568,39 +3567,23 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p)
|| code == COMPOUND_EXPR)) || code == COMPOUND_EXPR))
tclass = tcc_binary; tclass = tcc_binary;
else if (tclass == tcc_expression && code == SAVE_EXPR
&& ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
{
/* If we've already found a CVAL1 or CVAL2, this expression is
two complex to handle. */
if (*cval1 || *cval2)
return 0;
tclass = tcc_unary;
*save_p = 1;
}
switch (tclass) switch (tclass)
{ {
case tcc_unary: case tcc_unary:
return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p); return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2);
case tcc_binary: case tcc_binary:
return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p) return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2)
&& twoval_comparison_p (TREE_OPERAND (arg, 1), && twoval_comparison_p (TREE_OPERAND (arg, 1), cval1, cval2));
cval1, cval2, save_p));
case tcc_constant: case tcc_constant:
return 1; return 1;
case tcc_expression: case tcc_expression:
if (code == COND_EXPR) if (code == COND_EXPR)
return (twoval_comparison_p (TREE_OPERAND (arg, 0), return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2)
cval1, cval2, save_p) && twoval_comparison_p (TREE_OPERAND (arg, 1), cval1, cval2)
&& twoval_comparison_p (TREE_OPERAND (arg, 1), && twoval_comparison_p (TREE_OPERAND (arg, 2), cval1, cval2));
cval1, cval2, save_p)
&& twoval_comparison_p (TREE_OPERAND (arg, 2),
cval1, cval2, save_p));
return 0; return 0;
case tcc_comparison: case tcc_comparison:
...@@ -8781,9 +8764,8 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -8781,9 +8764,8 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST) if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
{ {
tree cval1 = 0, cval2 = 0; tree cval1 = 0, cval2 = 0;
int save_p = 0;
if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p) if (twoval_comparison_p (arg0, &cval1, &cval2)
/* Don't handle degenerate cases here; they should already /* Don't handle degenerate cases here; they should already
have been handled anyway. */ have been handled anyway. */
&& cval1 != 0 && cval2 != 0 && cval1 != 0 && cval2 != 0
...@@ -8856,12 +8838,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -8856,12 +8838,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
return omit_one_operand_loc (loc, type, integer_one_node, arg0); return omit_one_operand_loc (loc, type, integer_one_node, arg0);
} }
if (save_p)
{
tem = save_expr (build2 (code, type, cval1, cval2));
protected_set_expr_location (tem, loc);
return tem;
}
return fold_build2_loc (loc, code, type, cval1, cval2); return fold_build2_loc (loc, code, type, cval1, cval2);
} }
} }
......
2018-04-06 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/85213
* c-c++-common/ubsan/pr85213.c: New test.
2018-04-06 Richard Biener <rguenther@suse.de> 2018-04-06 Richard Biener <rguenther@suse.de>
PR middle-end/85180 PR middle-end/85180
......
/* PR sanitizer/85213 */
/* { dg-do compile } */
/* { dg-options "-O1 -fsanitize=undefined -fcompare-debug" } */
int
foo (int x)
{
return (__builtin_expect (({ x != 0; }) ? 0 : 1, 3) == 0) * -1 << 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment