diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-12-15 15:36:26 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-12-15 15:36:26 +0100 |
commit | a72610d4320925787d635cb4ddb8a40967e05bc3 (patch) | |
tree | 396cbb2afd84f1aa78d9ca5c6710dbc2fa445440 /gcc | |
parent | 5b85ad7d19aa1428b4f657bbbd5bf39d34ecbb14 (diff) | |
download | gcc-a72610d4320925787d635cb4ddb8a40967e05bc3.zip gcc-a72610d4320925787d635cb4ddb8a40967e05bc3.tar.gz gcc-a72610d4320925787d635cb4ddb8a40967e05bc3.tar.bz2 |
re PR sanitizer/81281 (UBSAN: false positive, dropped promotion to long type.)
PR sanitizer/81281
* match.pd ((T)(P + A) - (T)P -> (T) A): Use @@0 instead of @0 and
convert? on @0 instead of convert. Check type of @1, not @0.
((T)P - (T)(P + A) -> -(T) A): Use @@0 instead of @0 and
convert? on @0 instead of convert. Check type of @1, not @0.
((T)(P + A) - (T)(P + B) -> (T)A - (T)B): Use @@0 instead of @0,
only optimize if either both @1 and @2 types are narrower
precision, or both are wider or equal precision, and in the former
case only if both have undefined overflow.
* gcc.dg/pr81281-3.c: New test.
From-SVN: r255696
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/match.pd | 45 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr81281-3.c | 105 |
4 files changed, 147 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3282f48..8d655ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2017-12-15 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/81281 + * match.pd ((T)(P + A) - (T)P -> (T) A): Use @@0 instead of @0 and + convert? on @0 instead of convert. Check type of @1, not @0. + ((T)P - (T)(P + A) -> -(T) A): Use @@0 instead of @0 and + convert? on @0 instead of convert. Check type of @1, not @0. + ((T)(P + A) - (T)(P + B) -> (T)A - (T)B): Use @@0 instead of @0, + only optimize if either both @1 and @2 types are narrower + precision, or both are wider or equal precision, and in the former + case only if both have undefined overflow. + 2017-12-15 Richard Biener <rguenther@suse.de> PR lto/83388 diff --git a/gcc/match.pd b/gcc/match.pd index 0a4ff6b..3943ace 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1784,8 +1784,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (T)(P + A) - (T)P -> (T) A */ (simplify - (minus (convert (plus:c @0 @1)) - (convert @0)) + (minus (convert (plus:c @@0 @1)) + (convert? @0)) (if (element_precision (type) <= element_precision (TREE_TYPE (@1)) /* For integer types, if A has a smaller type than T the result depends on the possible @@ -1794,8 +1794,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) However, if an overflow in P + A would cause undefined behavior, we can assume that there is no overflow. */ - || (INTEGRAL_TYPE_P (TREE_TYPE (@0)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))) + || (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1)))) (convert @1))) (simplify (minus (convert (pointer_plus @@0 @1)) @@ -1818,8 +1818,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (T)P - (T)(P + A) -> -(T) A */ (simplify - (minus (convert @0) - (convert (plus:c @0 @1))) + (minus (convert? @0) + (convert (plus:c @@0 @1))) (if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type) && element_precision (type) <= element_precision (TREE_TYPE (@1))) @@ -1833,8 +1833,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) However, if an overflow in P + A would cause undefined behavior, we can assume that there is no overflow. */ - || (INTEGRAL_TYPE_P (TREE_TYPE (@0)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))) + || (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1)))) (negate (convert @1))))) (simplify (minus (convert @0) @@ -1862,23 +1862,28 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (T)(P + A) - (T)(P + B) -> (T)A - (T)B */ (simplify - (minus (convert (plus:c @0 @1)) + (minus (convert (plus:c @@0 @1)) (convert (plus:c @0 @2))) (if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_UNDEFINED (type) - && element_precision (type) <= element_precision (TREE_TYPE (@1))) + && element_precision (type) <= element_precision (TREE_TYPE (@1)) + && element_precision (type) <= element_precision (TREE_TYPE (@2))) (with { tree utype = unsigned_type_for (type); } (convert (minus (convert:utype @1) (convert:utype @2)))) - (if (element_precision (type) <= element_precision (TREE_TYPE (@1)) - /* For integer types, if A has a smaller type - than T the result depends on the possible - overflow in P + A. - E.g. T=size_t, A=(unsigned)429497295, P>0. - However, if an overflow in P + A would cause - undefined behavior, we can assume that there - is no overflow. */ - || (INTEGRAL_TYPE_P (TREE_TYPE (@0)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))) + (if (((element_precision (type) <= element_precision (TREE_TYPE (@1))) + == (element_precision (type) <= element_precision (TREE_TYPE (@2)))) + && (element_precision (type) <= element_precision (TREE_TYPE (@1)) + /* For integer types, if A has a smaller type + than T the result depends on the possible + overflow in P + A. + E.g. T=size_t, A=(unsigned)429497295, P>0. + However, if an overflow in P + A would cause + undefined behavior, we can assume that there + is no overflow. */ + || (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && INTEGRAL_TYPE_P (TREE_TYPE (@2)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@2))))) (minus (convert @1) (convert @2))))) (simplify (minus (convert (pointer_plus @@0 @1)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 176a7b9..e119691 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-12-15 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/81281 + * gcc.dg/pr81281-3.c: New test. + 2017-12-15 Justin Squirek <squirek@adacore.com> * gnat.dg/aliasing4.adb: New testcase. diff --git a/gcc/testsuite/gcc.dg/pr81281-3.c b/gcc/testsuite/gcc.dg/pr81281-3.c new file mode 100644 index 0000000..e491835 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr81281-3.c @@ -0,0 +1,105 @@ +/* PR sanitizer/81281 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "\[+=-] \?123\[ ;]" "optimized" } } */ + +#ifdef __SIZEOF_INT128__ +__int128 +f1 (int a, long long b) +{ + __int128 f = 123 + a; + __int128 g = 123 + b; + return f - g; +} +#endif + +signed char +f2 (int a, long long b) +{ + signed char f = 123 + a; + signed char g = 123 + b; + return f - g; +} + +signed char +f3 (unsigned int a, unsigned long long b) +{ + signed char f = 123 + a; + signed char g = 123 + b; + return f - g; +} + +unsigned char +f4 (unsigned int a, unsigned long long b) +{ + unsigned char f = 123 + a; + unsigned char g = 123 + b; + return f - g; +} + +/* This isn't optimized yet. */ +#if 0 +long long +f5 (int a) +{ + long long f = 123 + a; + long long g = 123; + return f - g; +} +#endif + +signed char +f6 (long long a) +{ + signed char f = 123 + a; + signed char g = 123; + return f - g; +} + +signed char +f7 (unsigned int a) +{ + signed char f = 123 + a; + signed char g = 123; + return f - g; +} + +unsigned char +f8 (unsigned long int a) +{ + unsigned char f = 123 + a; + unsigned char g = 123; + return f - g; +} + +long long +f9 (int a) +{ + long long f = 123; + long long g = 123 + a; + return f - g; +} + +signed char +f10 (long long a) +{ + signed char f = 123; + signed char g = 123 + a; + return f - g; +} + +signed char +f11 (unsigned int a) +{ + signed char f = 123; + signed char g = 123 + a; + return f - g; +} + +unsigned char +f12 (unsigned long int a) +{ + unsigned char f = 123; + unsigned char g = 123 + a; + return f - g; +} |