Commit 6b6ae9eb by Marek Polacek Committed by Marek Polacek

re PR sanitizer/80536 (UBSAN: compile time segfault)

	PR sanitizer/80536
	PR sanitizer/80386
	* cp-gimplify.c (cp_fold): Handle SAVE_EXPR.

	* tree.c (save_expr): Don't fold the expression.

	* c-c++-common/ubsan/pr80536.c: New test.
	* g++.dg/ubsan/pr80386.C: New test.

From-SVN: r248124
parent c0c24822
2017-05-16 Marek Polacek <polacek@redhat.com>
PR sanitizer/80536
PR sanitizer/80386
* tree.c (save_expr): Don't fold the expression.
2017-05-16 Uros Bizjak <ubizjak@gmail.com> 2017-05-16 Uros Bizjak <ubizjak@gmail.com>
* config/i386.i386.md (*movsi_internal): Split (?rm,*y) alternative * config/i386.i386.md (*movsi_internal): Split (?rm,*y) alternative
......
2017-05-16 Marek Polacek <polacek@redhat.com>
PR sanitizer/80536
PR sanitizer/80386
* cp-gimplify.c (cp_fold): Handle SAVE_EXPR.
2017-05-16 Nathan Sidwell <nathan@acm.org> 2017-05-16 Nathan Sidwell <nathan@acm.org>
* name-lookup.c (check_local_shadow): New, broke out of ... * name-lookup.c (check_local_shadow): New, broke out of ...
......
...@@ -2428,6 +2428,15 @@ cp_fold (tree x) ...@@ -2428,6 +2428,15 @@ cp_fold (tree x)
x = fold (x); x = fold (x);
break; break;
case SAVE_EXPR:
/* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
folding, evaluates to an invariant. In that case no need to wrap
this folded tree with a SAVE_EXPR. */
r = cp_fold (TREE_OPERAND (x, 0));
if (tree_invariant_p (r))
x = r;
break;
default: default:
return org_x; return org_x;
} }
......
2017-05-16 Marek Polacek <polacek@redhat.com>
PR sanitizer/80536
PR sanitizer/80386
* c-c++-common/ubsan/pr80536.c: New test.
* g++.dg/ubsan/pr80386.C: New test.
2017-05-16 Tamar Christina <tamar.christina@arm.com> 2017-05-16 Tamar Christina <tamar.christina@arm.com>
* gcc.target/arm/armv8_2-fp16-neon-1.c (vceqz): Fix regex. * gcc.target/arm/armv8_2-fp16-neon-1.c (vceqz): Fix regex.
......
/* PR sanitizer/80536 */
/* { dg-do compile } */
/* { dg-options "-fsanitize=undefined" } */
int
foo (int i)
{
return ((i * (unsigned long long) (-0 + 1UL)) * 2) % 1;
}
// PR sanitizer/80386
// { dg-do run }
// { dg-options "-fsanitize=undefined -fno-sanitize-recover" }
static unsigned long long int i = 13996271126042720493ULL;
int
main ()
{
int r = (((2921 + 0) - short(i)) + 0x7fffffff) >> 0;
asm volatile ("" : "+g" (r));
return 0;
}
...@@ -3337,7 +3337,6 @@ tree_invariant_p (tree t) ...@@ -3337,7 +3337,6 @@ tree_invariant_p (tree t)
tree tree
save_expr (tree expr) save_expr (tree expr)
{ {
tree t = fold (expr);
tree inner; tree inner;
/* If the tree evaluates to a constant, then we don't want to hide that /* If the tree evaluates to a constant, then we don't want to hide that
...@@ -3345,33 +3344,32 @@ save_expr (tree expr) ...@@ -3345,33 +3344,32 @@ save_expr (tree expr)
However, a read-only object that has side effects cannot be bypassed. However, a read-only object that has side effects cannot be bypassed.
Since it is no problem to reevaluate literals, we just return the Since it is no problem to reevaluate literals, we just return the
literal node. */ literal node. */
inner = skip_simple_arithmetic (t); inner = skip_simple_arithmetic (expr);
if (TREE_CODE (inner) == ERROR_MARK) if (TREE_CODE (inner) == ERROR_MARK)
return inner; return inner;
if (tree_invariant_p_1 (inner)) if (tree_invariant_p_1 (inner))
return t; return expr;
/* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
it means that the size or offset of some field of an object depends on it means that the size or offset of some field of an object depends on
the value within another field. the value within another field.
Note that it must not be the case that T contains both a PLACEHOLDER_EXPR Note that it must not be the case that EXPR contains both a PLACEHOLDER_EXPR
and some variable since it would then need to be both evaluated once and and some variable since it would then need to be both evaluated once and
evaluated more than once. Front-ends must assure this case cannot evaluated more than once. Front-ends must assure this case cannot
happen by surrounding any such subexpressions in their own SAVE_EXPR happen by surrounding any such subexpressions in their own SAVE_EXPR
and forcing evaluation at the proper time. */ and forcing evaluation at the proper time. */
if (contains_placeholder_p (inner)) if (contains_placeholder_p (inner))
return t; return expr;
t = build1 (SAVE_EXPR, TREE_TYPE (expr), t); expr = build1_loc (EXPR_LOCATION (expr), SAVE_EXPR, TREE_TYPE (expr), expr);
SET_EXPR_LOCATION (t, EXPR_LOCATION (expr));
/* This expression might be placed ahead of a jump to ensure that the /* This expression might be placed ahead of a jump to ensure that the
value was computed on both sides of the jump. So make sure it isn't value was computed on both sides of the jump. So make sure it isn't
eliminated as dead. */ eliminated as dead. */
TREE_SIDE_EFFECTS (t) = 1; TREE_SIDE_EFFECTS (expr) = 1;
return t; return expr;
} }
/* Look inside EXPR into any simple arithmetic operations. Return the /* Look inside EXPR into any simple arithmetic operations. Return the
......
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