mirror of git://gcc.gnu.org/git/gcc.git
flags.h (POINTER_TYPE_OVERFLOW_UNDEFINED): Define.
gcc/: * 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/: * gcc.dg/strict-overflow-6.c: New. * gcc.dg/no-strict-overflow-7.c: New. * gcc.dg/Wstrict-overflow-22.c: New. From-SVN: r134287
This commit is contained in:
parent
3a5a8be120
commit
4c9db6e07a
|
|
@ -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>
|
2008-04-13 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* m32.c (m32c_pushm_popm): Use crtl->retrun_rtx.
|
* m32.c (m32c_pushm_popm): Use crtl->retrun_rtx.
|
||||||
|
|
|
||||||
|
|
@ -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
|
attempt to determine whether an operation on signed numbers will
|
||||||
overflow must be written carefully to not actually involve overflow.
|
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
|
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{-fwrapv} is used, there is no difference between
|
||||||
@option{-fstrict-overflow} and @option{-fno-strict-overflow}. With
|
@option{-fstrict-overflow} and @option{-fno-strict-overflow} for
|
||||||
@option{-fwrapv} certain types of overflow are permitted. For
|
integers. With @option{-fwrapv} certain types of overflow are
|
||||||
example, if the compiler gets an overflow when doing arithmetic on
|
permitted. For example, if the compiler gets an overflow when doing
|
||||||
constants, the overflowed value can still be used with
|
arithmetic on constants, the overflowed value can still be used with
|
||||||
@option{-fwrapv}, but not otherwise.
|
@option{-fwrapv}, but not otherwise.
|
||||||
|
|
||||||
The @option{-fstrict-overflow} option is enabled at levels
|
The @option{-fstrict-overflow} option is enabled at levels
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,9 @@ extern bool flag_instrument_functions_exclude_p (tree fndecl);
|
||||||
#define TYPE_OVERFLOW_TRAPS(TYPE) \
|
#define TYPE_OVERFLOW_TRAPS(TYPE) \
|
||||||
(!TYPE_UNSIGNED (TYPE) && flag_trapv)
|
(!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
|
/* Names for the different levels of -Wstrict-overflow=N. The numeric
|
||||||
values here correspond to N. */
|
values here correspond to N. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
because pointer arithmetic is restricted to retain within an
|
||||||
object and overflow on pointer differences is undefined as of
|
object and overflow on pointer differences is undefined as of
|
||||||
6.5.6/8 and /9 with respect to the signed ptrdiff_t. */
|
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;
|
tree signed_size_type_node;
|
||||||
signed_size_type_node = signed_type_for (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
|
else
|
||||||
offset1 = fold_convert (signed_size_type_node, offset1);
|
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);
|
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 undefined overflow we can only associate constants
|
||||||
with one variable. */
|
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)))
|
|| (INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type)))
|
||||||
&& var0 && var1)
|
&& var0 && var1)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2008-04-14 Samuel Tardieu <sam@rfc1149.net>
|
||||||
|
|
||||||
* gnat.dg/specs/storage.ads: Fix expected error message.
|
* gnat.dg/specs/storage.ads: Fix expected error message.
|
||||||
|
|
|
||||||
|
|
@ -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" } */
|
||||||
|
}
|
||||||
|
|
@ -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" } } */
|
||||||
|
|
@ -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" } } */
|
||||||
Loading…
Reference in New Issue