aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-12-15 15:36:26 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-12-15 15:36:26 +0100
commita72610d4320925787d635cb4ddb8a40967e05bc3 (patch)
tree396cbb2afd84f1aa78d9ca5c6710dbc2fa445440 /gcc
parent5b85ad7d19aa1428b4f657bbbd5bf39d34ecbb14 (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/match.pd45
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr81281-3.c105
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;
+}