--- gcc/tree-ssa-forwprop.c	2014-06-25 09:16:00.640772481 +0200
+++ gcc/tree-ssa-forwprop.c	2014-06-25 09:51:48.343057122 +0200
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
 #include "tree-pass.h"
 #include "langhooks.h"
 #include "flags.h"
+#include "diagnostic.h"
 #include "expr.h"
 #include "cfgloop.h"
 #include "optabs.h"
@@ -2679,6 +2680,16 @@ associate_plusminus (gimple_stmt_iterato
 			  && !FIXED_POINT_TYPE_P (TREE_TYPE (a))
 			  && (TYPE_PRECISION (TREE_TYPE (rhs1))
 			      <= TYPE_PRECISION (TREE_TYPE (a))
+			      /* 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.  */
+			      || (!POINTER_TYPE_P (TREE_TYPE (p))
+				  && INTEGRAL_TYPE_P (TREE_TYPE (a))
+				  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (a)))
 			      /* For pointer types, if the conversion of A to
 				 the final type requires a sign- or
 				 zero-extension, then we have to punt - it is
@@ -2687,6 +2698,16 @@ associate_plusminus (gimple_stmt_iterato
 				  && TREE_CODE (a) == INTEGER_CST
 				  && tree_int_cst_sign_bit (a) == 0)))
 			{
+			  if (issue_strict_overflow_warning
+			      (WARN_STRICT_OVERFLOW_MISC)
+			      && TYPE_PRECISION (TREE_TYPE (rhs1))
+				 > TYPE_PRECISION (TREE_TYPE (a))
+			      && !POINTER_TYPE_P (TREE_TYPE (p)))
+			    warning_at (gimple_location (stmt),
+					OPT_Wstrict_overflow,
+					"assuming signed overflow does not "
+					"occur when assuming that "
+					"(T)(P + A) - (T)P is always (T)A");
 			  if (useless_type_conversion_p (TREE_TYPE (rhs1),
 							 TREE_TYPE (a)))
 			    code = TREE_CODE (a);
