Message ID | 20181105093337.GM11625@tucnak |
---|---|
State | New |
Headers | show |
Series | Fix -fsanitize=undefined vs. x + y < x (PR sanitizer/87837) | expand |
On Mon, 5 Nov 2018, Jakub Jelinek wrote: > Hi! > > I wish I had a better fix, but I don't, trying to sanitize signed integer > arithmetics in the FEs already before any folding there is complicated by > that arithmetics being created just in way too many spots. I suppose we could play some tricks and "unset" TYPE_OVERFLOW_SANITIZED after instrumentation finished? > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. Richard. > 2018-11-05 Jakub Jelinek <jakub@redhat.com> > > PR sanitizer/87837 > * match.pd (X + Y < X): Don't optimize if TYPE_OVERFLOW_SANITIZED. > > * c-c++-common/ubsan/pr87837.c: New test. > > --- gcc/match.pd.jj 2018-10-31 10:33:07.438686055 +0100 > +++ gcc/match.pd 2018-11-01 10:26:44.251883633 +0100 > @@ -1572,6 +1572,7 @@ (define_operator_list COND_TERNARY > (op:c (plus:c@2 @0 @1) @1) > (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) > && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) > + && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)) > && (CONSTANT_CLASS_P (@0) || single_use (@2))) > (op @0 { build_zero_cst (TREE_TYPE (@0)); })))) > /* For equality, this is also true with wrapping overflow. */ > --- gcc/testsuite/c-c++-common/ubsan/pr87837.c.jj 2018-11-01 10:37:35.159186004 +0100 > +++ gcc/testsuite/c-c++-common/ubsan/pr87837.c 2018-11-01 10:39:56.162868607 +0100 > @@ -0,0 +1,18 @@ > +/* PR sanitizer/87837 */ > +/* { dg-do run } */ > +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */ > + > +int > +foo (int n) > +{ > + return n + __INT_MAX__ < n; > +} > + > +int > +main () > +{ > + volatile int a = foo (1); > + return 0; > +} > + > +/* { dg-output "signed integer overflow: 1 \\+ 2147483647 cannot be represented in type 'int'" } */ > > Jakub >
On Mon, Nov 05, 2018 at 11:03:28AM +0100, Richard Biener wrote: > On Mon, 5 Nov 2018, Jakub Jelinek wrote: > > > Hi! > > > > I wish I had a better fix, but I don't, trying to sanitize signed integer > > arithmetics in the FEs already before any folding there is complicated by > > that arithmetics being created just in way too many spots. > > I suppose we could play some tricks and "unset" TYPE_OVERFLOW_SANITIZED > after instrumentation finished? Yes, e.g. have some cfun-> flag or property that would be cleared during the ubsan pass (and clear from the beginning if not sanitizing integer overflows). Jakub
--- gcc/match.pd.jj 2018-10-31 10:33:07.438686055 +0100 +++ gcc/match.pd 2018-11-01 10:26:44.251883633 +0100 @@ -1572,6 +1572,7 @@ (define_operator_list COND_TERNARY (op:c (plus:c@2 @0 @1) @1) (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) + && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)) && (CONSTANT_CLASS_P (@0) || single_use (@2))) (op @0 { build_zero_cst (TREE_TYPE (@0)); })))) /* For equality, this is also true with wrapping overflow. */ --- gcc/testsuite/c-c++-common/ubsan/pr87837.c.jj 2018-11-01 10:37:35.159186004 +0100 +++ gcc/testsuite/c-c++-common/ubsan/pr87837.c 2018-11-01 10:39:56.162868607 +0100 @@ -0,0 +1,18 @@ +/* PR sanitizer/87837 */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=signed-integer-overflow -Wno-unused-variable" } */ + +int +foo (int n) +{ + return n + __INT_MAX__ < n; +} + +int +main () +{ + volatile int a = foo (1); + return 0; +} + +/* { dg-output "signed integer overflow: 1 \\+ 2147483647 cannot be represented in type 'int'" } */