diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0288-2011-05-20-Richard-Guenther-rguenther-suse.de.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0288-2011-05-20-Richard-Guenther-rguenther-suse.de.patch | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0288-2011-05-20-Richard-Guenther-rguenther-suse.de.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0288-2011-05-20-Richard-Guenther-rguenther-suse.de.patch new file mode 100644 index 0000000000..ff2cb06641 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0288-2011-05-20-Richard-Guenther-rguenther-suse.de.patch @@ -0,0 +1,117 @@ +From 24f5b59f5c9418d39087b36dd0d275f71ac4dca5 Mon Sep 17 00:00:00 2001 +From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Fri, 20 May 2011 15:08:56 +0000 +Subject: [PATCH] 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. + + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173955 138bc75d-0d04-0410-961f-82ee72b054a4 + +index 0efa0eb..dcb39c1 100644 +new file mode 100644 +index 0000000..1b53d3c +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/torture/pr49079.c +@@ -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; ++} +diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c +index 6490c5e..2dacd44 100644 +--- a/gcc/tree-dfa.c ++++ b/gcc/tree-dfa.c +@@ -709,6 +709,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) +@@ -739,6 +740,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: +@@ -926,9 +929,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. */ ++ ++ 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; + +- That is of course only true if the base object is not a decl. */ ++ /* In case of a decl or constant base object we can do better. */ + + if (DECL_P (exp)) + { +@@ -938,12 +948,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 +-- +1.7.0.4 + |