mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-18 23:51:08 +08:00
re PR tree-optimization/49079 (Bogus constant folding)
2011-05-20 Richard Guenther <rguenther@suse.de> PR tree-optimization/49079 * tree-dfa.c (get_ref_base_and_extent): Handle view-converting MEM_REFs correctly for the trailing array access detection. Special case constants the same way as decls for overall size constraining. * gcc.dg/torture/pr49079.c: New testcase. From-SVN: r173954
This commit is contained in:
parent
3cda91d863
commit
90ff582fb1
@ -1,3 +1,11 @@
|
||||
2011-05-20 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/49079
|
||||
* tree-dfa.c (get_ref_base_and_extent): Handle view-converting
|
||||
MEM_REFs correctly for the trailing array access detection.
|
||||
Special case constants the same way as decls for overall size
|
||||
constraining.
|
||||
|
||||
2011-05-20 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* config/i386/mingw32.h (OUTPUT_QUOTED_STRING): Fix macro
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-05-20 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/49079
|
||||
* gcc.dg/torture/pr49079.c: New testcase.
|
||||
|
||||
2011-05-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/49073
|
||||
|
31
gcc/testsuite/gcc.dg/torture/pr49079.c
Normal file
31
gcc/testsuite/gcc.dg/torture/pr49079.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
struct Ustr
|
||||
{
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
ustr_xi__embed_val_get(const unsigned char *data)
|
||||
{
|
||||
return (unsigned int)data[0];
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) zero(void) { return 0; }
|
||||
|
||||
static unsigned int
|
||||
ustr_len(const struct Ustr *s1)
|
||||
{
|
||||
return ustr_xi__embed_val_get(s1->data + 1 + zero());
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
if (ustr_len (((struct Ustr *) "\x01" "\x0002" "s2")) != 2)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
@ -714,6 +714,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||
tree size_tree = NULL_TREE;
|
||||
HOST_WIDE_INT bit_offset = 0;
|
||||
bool seen_variable_array_ref = false;
|
||||
tree base_type;
|
||||
|
||||
/* First get the final access size from just the outermost expression. */
|
||||
if (TREE_CODE (exp) == COMPONENT_REF)
|
||||
@ -744,6 +745,8 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||
and find the ultimate containing object. */
|
||||
while (1)
|
||||
{
|
||||
base_type = TREE_TYPE (exp);
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case BIT_FIELD_REF:
|
||||
@ -931,9 +934,16 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||
the array. The simplest way to conservatively deal with this
|
||||
is to punt in the case that offset + maxsize reaches the
|
||||
base type boundary. This needs to include possible trailing padding
|
||||
that is there for alignment purposes.
|
||||
that is there for alignment purposes. */
|
||||
|
||||
That is of course only true if the base object is not a decl. */
|
||||
if (seen_variable_array_ref
|
||||
&& maxsize != -1
|
||||
&& (!host_integerp (TYPE_SIZE (base_type), 1)
|
||||
|| (bit_offset + maxsize
|
||||
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (base_type)))))
|
||||
maxsize = -1;
|
||||
|
||||
/* In case of a decl or constant base object we can do better. */
|
||||
|
||||
if (DECL_P (exp))
|
||||
{
|
||||
@ -943,12 +953,14 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||
&& host_integerp (DECL_SIZE (exp), 1))
|
||||
maxsize = TREE_INT_CST_LOW (DECL_SIZE (exp)) - bit_offset;
|
||||
}
|
||||
else if (seen_variable_array_ref
|
||||
&& maxsize != -1
|
||||
&& (!host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
||||
|| (bit_offset + maxsize
|
||||
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
|
||||
maxsize = -1;
|
||||
else if (CONSTANT_CLASS_P (exp))
|
||||
{
|
||||
/* If maxsize is unknown adjust it according to the size of the
|
||||
base type constant. */
|
||||
if (maxsize == -1
|
||||
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1))
|
||||
maxsize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))) - bit_offset;
|
||||
}
|
||||
|
||||
/* ??? Due to negative offsets in ARRAY_REF we can end up with
|
||||
negative bit_offset here. We might want to store a zero offset
|
||||
|
Loading…
x
Reference in New Issue
Block a user