public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH RFC: Warn about pointer wraparound with -Wstrict-overflow
@ 2008-04-07 20:46 Ian Lance Taylor
  2008-04-08  9:31 ` Richard Guenther
                   ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Ian Lance Taylor @ 2008-04-07 20:46 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1129 bytes --]

I'm testing this patch as a response to
    http://www.kb.cert.org/vuls/id/162289

This patch treats undefined pointer wraparound optimizations as an
instance of undefined signed overflow optimizations (they are of
course different, but they seem similar to users not educated in
standardese).  You will get a warning with -Wstrict-overflow, and you
can disable the optimization with -fno-strict-overflow.

My plan is to backport this patch to the gcc 4.2 and 4.3 branches.

Any comments or concerns?

Ian


gcc/ChangeLog:
2008-04-07  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.

gcc/testsuite/ChangeLog:
2008-04-07  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.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Warn about pointer wraparound with -Wstrict-overflow --]
[-- Type: text/x-patch, Size: 5108 bytes --]

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 133985)
+++ gcc/doc/invoke.texi	(working copy)
@@ -6161,6 +6161,14 @@ using twos complement arithmetic.  When 
 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 + i >
+p} is always true for a pointer @code{p} and integer @code{i}.  This
+assumption is only valid if pointer wraparound is undefined, as the
+expression is false if @code{p + i} overflows.
+
 See also the @option{-fwrapv} option.  Using @option{-fwrapv} means
 that signed overflow is fully defined: it wraps.  When
 @option{-fwrapv} is used, there is no difference between
Index: gcc/flags.h
===================================================================
--- gcc/flags.h	(revision 133985)
+++ gcc/flags.h	(working copy)
@@ -332,6 +332,10 @@ extern bool flag_instrument_functions_ex
 #define TYPE_OVERFLOW_TRAPS(TYPE) \
   (!TYPE_UNSIGNED (TYPE) && flag_trapv)
 
+/* True if pointer types have undefined overflow.  */
+#define POINTER_TYPE_OVERFLOW_UNDEFINED \
+  (!flag_wrapv && !flag_trapv && flag_strict_overflow)
+
 /* Names for the different levels of -Wstrict-overflow=N.  The numeric
    values here correspond to N.  */
 
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 133985)
+++ gcc/fold-const.c	(working copy)
@@ -8564,7 +8564,9 @@ fold_comparison (enum tree_code code, tr
 	     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);
@@ -8583,6 +8585,12 @@ fold_comparison (enum tree_code code, tr
 	      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);
 	    }
 	}
@@ -9707,7 +9715,7 @@ fold_binary (enum tree_code code, tree t
 
 	  /* 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)
 	    {
Index: gcc/testsuite/gcc.dg/strict-overflow-6.c
===================================================================
--- gcc/testsuite/gcc.dg/strict-overflow-6.c	(revision 0)
+++ gcc/testsuite/gcc.dg/strict-overflow-6.c	(revision 0)
@@ -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" } } */
Index: gcc/testsuite/gcc.dg/no-strict-overflow-7.c
===================================================================
--- gcc/testsuite/gcc.dg/no-strict-overflow-7.c	(revision 0)
+++ gcc/testsuite/gcc.dg/no-strict-overflow-7.c	(revision 0)
@@ -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" } } */
Index: gcc/testsuite/gcc.dg/Wstrict-overflow-22.c
===================================================================
--- gcc/testsuite/gcc.dg/Wstrict-overflow-22.c	(revision 0)
+++ gcc/testsuite/gcc.dg/Wstrict-overflow-22.c	(revision 0)
@@ -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" } */
+}

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2008-04-18 15:24 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-07 20:46 PATCH RFC: Warn about pointer wraparound with -Wstrict-overflow Ian Lance Taylor
2008-04-08  9:31 ` Richard Guenther
2008-04-08 15:16   ` Ian Lance Taylor
2008-04-08 16:31     ` Richard Guenther
2008-04-08 18:15       ` Ian Lance Taylor
2008-04-11 10:04         ` gsan
2008-04-14 19:34           ` Ian Lance Taylor
2008-04-08 18:59 ` Mark Mitchell
2008-04-08 19:01   ` Ian Lance Taylor
2008-04-08 19:08     ` Mark Mitchell
2008-04-08 21:00       ` Ian Lance Taylor
2008-04-08 23:50         ` Mark Mitchell
2008-04-08 19:40   ` Jakub Jelinek
2008-04-08 21:08     ` Ian Lance Taylor
2008-04-08 21:18       ` Richard Guenther
2008-04-08 22:16         ` Ian Lance Taylor
2008-04-08 20:57   ` Richard Guenther
2008-04-08 21:47   ` Paul Brook
2008-04-08 21:54     ` Andrew Pinski
2008-04-08 21:54       ` Mark Mitchell
2008-04-08 21:56         ` Richard Guenther
2008-04-08 23:48           ` Mark Mitchell
2008-04-10 18:22   ` Joseph S. Myers
2008-04-14 20:02 ` PATCH COMMITTED: " Ian Lance Taylor
2008-04-15  9:26   ` Richard Guenther
2008-04-15 14:28     ` Ian Lance Taylor
2008-04-15 17:49     ` Ian Lance Taylor
2008-04-17  6:24     ` Ian Lance Taylor
2008-04-18 16:22       ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).