mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-13 13:54:05 +08:00
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>
|
||||
|
||||
* 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
|
||||
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
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
13
gcc/testsuite/gcc.dg/Wstrict-overflow-22.c
Normal file
13
gcc/testsuite/gcc.dg/Wstrict-overflow-22.c
Normal file
@ -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" } */
|
||||
}
|
16
gcc/testsuite/gcc.dg/no-strict-overflow-7.c
Normal file
16
gcc/testsuite/gcc.dg/no-strict-overflow-7.c
Normal file
@ -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" } } */
|
16
gcc/testsuite/gcc.dg/strict-overflow-6.c
Normal file
16
gcc/testsuite/gcc.dg/strict-overflow-6.c
Normal file
@ -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
Block a user