aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/doc/invoke.texi19
-rw-r--r--gcc/flags.h3
-rw-r--r--gcc/fold-const.c12
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-overflow-22.c13
-rw-r--r--gcc/testsuite/gcc.dg/no-strict-overflow-7.c16
-rw-r--r--gcc/testsuite/gcc.dg/strict-overflow-6.c16
8 files changed, 88 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b15e712..d6c2be3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2008-04-14 Ian Lance Taylor <iant@google.com>
+
+ * flags.h (POINTER_TYPE_OVERFLOW_UNDEFINED): Define.
+ * fold-const.c (fold_comparison): If appropriate, test
+ POINTER_TYPE_OVERFLOW_UNDEFINED, and issue an overflow warning.
+ (fold_binary): Test POINTER_TYPE_OVERFLOW_UNDEFINED when
+ reassociating a pointer type.
+ * doc/invoke.texi (Optimize Options): Document that
+ -fstrict-overflow applies to pointer wraparound.
+
2008-04-13 Jan Hubicka <jh@suse.cz>
* m32.c (m32c_pushm_popm): Use crtl->retrun_rtx.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d8ae286..bb7be99 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6161,13 +6161,22 @@ using twos complement arithmetic. When this option is in effect any
attempt to determine whether an operation on signed numbers will
overflow must be written carefully to not actually involve overflow.
+This option also allows the compiler to assume strict pointer
+semantics: given a pointer to an object, if adding an offset to that
+pointer does not produce a pointer to the same object, the addition is
+undefined. This permits the compiler to conclude that @code{p + u >
+p} is always true for a pointer @code{p} and unsigned integer
+@code{u}. This assumption is only valid because pointer wraparound is
+undefined, as the expression is false if @code{p + u} overflows using
+twos complement arithmetic.
+
See also the @option{-fwrapv} option. Using @option{-fwrapv} means
-that signed overflow is fully defined: it wraps. When
+that integer signed overflow is fully defined: it wraps. When
@option{-fwrapv} is used, there is no difference between
-@option{-fstrict-overflow} and @option{-fno-strict-overflow}. With
-@option{-fwrapv} certain types of overflow are permitted. For
-example, if the compiler gets an overflow when doing arithmetic on
-constants, the overflowed value can still be used with
+@option{-fstrict-overflow} and @option{-fno-strict-overflow} for
+integers. With @option{-fwrapv} certain types of overflow are
+permitted. For example, if the compiler gets an overflow when doing
+arithmetic on constants, the overflowed value can still be used with
@option{-fwrapv}, but not otherwise.
The @option{-fstrict-overflow} option is enabled at levels
diff --git a/gcc/flags.h b/gcc/flags.h
index 686691c..e759695 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -332,6 +332,9 @@ extern bool flag_instrument_functions_exclude_p (tree fndecl);
#define TYPE_OVERFLOW_TRAPS(TYPE) \
(!TYPE_UNSIGNED (TYPE) && flag_trapv)
+/* True if pointer types have undefined overflow. */
+#define POINTER_TYPE_OVERFLOW_UNDEFINED (flag_strict_overflow)
+
/* Names for the different levels of -Wstrict-overflow=N. The numeric
values here correspond to N. */
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 66e72a7..ce5673e 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8568,7 +8568,9 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
because pointer arithmetic is restricted to retain within an
object and overflow on pointer differences is undefined as of
6.5.6/8 and /9 with respect to the signed ptrdiff_t. */
- else if (bitpos0 == bitpos1)
+ else if (bitpos0 == bitpos1
+ && ((code == EQ_EXPR || code == NE_EXPR)
+ || POINTER_TYPE_OVERFLOW_UNDEFINED))
{
tree signed_size_type_node;
signed_size_type_node = signed_type_for (size_type_node);
@@ -8587,6 +8589,12 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
else
offset1 = fold_convert (signed_size_type_node, offset1);
+ if (code != EQ_EXPR && code != NE_EXPR)
+ fold_overflow_warning (("assuming pointer wraparound does not "
+ "occur when comparing P +- C1 with "
+ "P +- C2"),
+ WARN_STRICT_OVERFLOW_COMPARISON);
+
return fold_build2 (code, type, offset0, offset1);
}
}
@@ -9711,7 +9719,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
/* With undefined overflow we can only associate constants
with one variable. */
- if ((POINTER_TYPE_P (type)
+ if (((POINTER_TYPE_P (type) && POINTER_TYPE_OVERFLOW_UNDEFINED)
|| (INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type)))
&& var0 && var1)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1f476fe..d87b121 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2008-04-14 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/strict-overflow-6.c: New.
+ * gcc.dg/no-strict-overflow-7.c: New.
+ * gcc.dg/Wstrict-overflow-22.c: New.
+
2008-04-14 Samuel Tardieu <sam@rfc1149.net>
* gnat.dg/specs/storage.ads: Fix expected error message.
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-22.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-22.c
new file mode 100644
index 0000000..4b84387
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-22.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=3" } */
+
+/* Source: Ian Lance Taylor. Based on strict-overflow-6.c. */
+
+/* We can only simplify the conditional when using strict overflow
+ semantics. */
+
+int
+foo (char* p)
+{
+ return p + 1000 < p; /* { dg-warning "assuming pointer wraparound does not occur" "correct warning" } */
+}
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-7.c b/gcc/testsuite/gcc.dg/no-strict-overflow-7.c
new file mode 100644
index 0000000..07ad27b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-strict-overflow-7.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor. Dual of strict-overflow-6.c. */
+
+/* We can only simplify the conditional when using strict overflow
+ semantics. */
+
+int
+foo (char* p)
+{
+ return p + 1000 < p;
+}
+
+/* { dg-final { scan-tree-dump "\[+\]\[ \]*1000" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/strict-overflow-6.c b/gcc/testsuite/gcc.dg/strict-overflow-6.c
new file mode 100644
index 0000000..ec1266d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strict-overflow-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */
+
+/* Source: Ian Lance Taylor. Dual of no-strict-overflow-7.c. */
+
+/* We can only simplify the conditional when using strict overflow
+ semantics. */
+
+int
+foo (char* p)
+{
+ return p + 1000 < p;
+}
+
+/* { dg-final { scan-tree-dump-not "\[+\]\[ \]*1000" "final_cleanup" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */