This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix for fold_negate_expr (PR sanitizer/63879)


On Wed, 19 Nov 2014, Marek Polacek wrote:

> The problem here is that negate_expr_p returns true (as it should)
> for UINT_MAX(OVF), but fold_negate_expr didn't actually fold it,
> and that is a no-no; if negate_expr_p is true, fold_negate_expr must
> not return NULL_TREE.  I added the following hunk for bootstrap and
> regtest for better coverage:
> 
> @@ -752,6 +755,12 @@ fold_negate_expr (location_t loc, tree t)
>        break;
>      }
>  
> +#ifdef ENABLE_CHECKING
> +  if (negate_expr_p (t))
> +    internal_error ("fold_negate_expr should never return NULL_TREE "
> +		    "if negate_expr_p is true");
> +#endif
> +
>    return NULL_TREE;
>  }
> 
> Fixed by adjusting fold_negate_expr so that it folds non-trapping
> wrapping constants.  The SANITIZE_SI_OVERFLOW check is important
> to not regress -Woverflow warnings (ug).
> 
> negate_expr_p hunk is to match the NEGATE_EXPR case in fold_negate_expr.
>  
> Bootstrapped/regtested on power8-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2014-11-19  Marek Polacek  <polacek@redhat.com>
> 
> 	PR sanitizer/63879
> 	* fold-const.c (negate_expr_p) <case NEGATE_EXPR>: Return
> 	!TYPE_OVERFLOW_SANITIZED.
> 	(fold_negate_expr) <case INTEGER_CST>: Fold when overflow
> 	does not trap and when overflow wraps, or when SANITIZE_SI_OVERFLOW
> 	is 0.
> 
> 	* c-c++-common/ubsan/pr63879-1.c: New test.
> 	* c-c++-common/ubsan/pr63879-2.c: New test.
> 
> diff --git gcc/fold-const.c gcc/fold-const.c
> index f6fb8af..719e06e 100644
> --- gcc/fold-const.c
> +++ gcc/fold-const.c
> @@ -408,9 +408,11 @@ negate_expr_p (tree t)
>  	      && TYPE_OVERFLOW_WRAPS (type));
>  
>      case FIXED_CST:
> -    case NEGATE_EXPR:
>        return true;
>  
> +    case NEGATE_EXPR:
> +      return !TYPE_OVERFLOW_SANITIZED (type);
> +
>      case REAL_CST:
>        /* We want to canonicalize to positive real constants.  Pretend
>           that only negative ones can be easily negated.  */
> @@ -555,7 +557,8 @@ fold_negate_expr (location_t loc, tree t)
>        tem = fold_negate_const (t, type);
>        if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
>  	  || (!TYPE_OVERFLOW_TRAPS (type)
> -	      && (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0))
> +	      && TYPE_OVERFLOW_WRAPS (type))
> +	  || (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0)
>  	return tem;
>        break;
>  
> diff --git gcc/testsuite/c-c++-common/ubsan/pr63879-1.c gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
> index e69de29..2035849 100644
> --- gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
> +++ gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
> @@ -0,0 +1,23 @@
> +/* PR sanitizer/63879 */
> +/* { dg-do compile } */
> +/* { dg-options "-fsanitize=undefined" } */
> +
> +struct A
> +{
> +  int inode;
> +} * a;
> +int b, c;
> +void
> +fn1 ()
> +{
> +  int d = 0;
> +  while (b)
> +    {
> +      if (a->inode)
> +        d++;
> +      a = 0;
> +    }
> +  c = d - 1;
> +  for (; c >= 0; c--)
> +    ;
> +}
> diff --git gcc/testsuite/c-c++-common/ubsan/pr63879-2.c gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
> index e69de29..34eb8e7 100644
> --- gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
> +++ gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
> @@ -0,0 +1,13 @@
> +/* PR sanitizer/63879 */
> +/* { dg-do compile } */
> +/* { dg-options "-fsanitize=undefined" } */
> +
> +int a;
> +void
> +fn1 ()
> +{
> +  int b = 2;
> +  for (; a;)
> +    while (b >= 0)
> +      b--;
> +}
> 
> 	Marek
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendoerffer, HRB 21284
(AG Nuernberg)
Maxfeldstrasse 5, 90409 Nuernberg, Germany


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]