summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-10 16:44:01 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-10 16:44:01 +0000
commit1eee24cf0a571f56674368c561e9ff0f78670c5f (patch)
treeca610c80b72b454616b08e05bf5c2ed82d666839
parent65a1f1e95e79080373d5a6e99455bcac551182ec (diff)
downloadppe42-gcc-1eee24cf0a571f56674368c561e9ff0f78670c5f.tar.gz
ppe42-gcc-1eee24cf0a571f56674368c561e9ff0f78670c5f.zip
2006-03-10 Richard Guenther <rguenther@suse.de>
PR middle-end/26565 * builtins.c (get_pointer_alignment): Handle component references for field alignment. * gcc.dg/torture/pr26565.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111934 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/builtins.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr26565.c28
4 files changed, 49 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d1f4a0ce6f1..77ce19e6b21 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-03-10 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/26565
+ * builtins.c (get_pointer_alignment): Handle component
+ references for field alignment.
+
2006-03-10 J"orn Rennecke <joern.rennecke@st.com>
* config.gcc (sh*-superh-elf, sh*elf (newlib)): Use newlib.h
diff --git a/gcc/builtins.c b/gcc/builtins.c
index f6095e84bed..1ce6083137a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -275,15 +275,21 @@ get_pointer_alignment (tree exp, unsigned int max_align)
case ADDR_EXPR:
/* See what we are pointing at and look at its alignment. */
exp = TREE_OPERAND (exp, 0);
+ while (handled_component_p (exp))
+ {
+ if (TREE_CODE (exp) == COMPONENT_REF)
+ align = MIN (align, DECL_ALIGN (TREE_OPERAND (exp, 1)));
+ exp = TREE_OPERAND (exp, 0);
+ }
if (TREE_CODE (exp) == FUNCTION_DECL)
- align = FUNCTION_BOUNDARY;
+ align = MIN (align, FUNCTION_BOUNDARY);
else if (DECL_P (exp))
- align = DECL_ALIGN (exp);
+ align = MIN (align, DECL_ALIGN (exp));
#ifdef CONSTANT_ALIGNMENT
else if (CONSTANT_CLASS_P (exp))
- align = CONSTANT_ALIGNMENT (exp, align);
+ align = MIN (align, (unsigned)CONSTANT_ALIGNMENT (exp, align));
#endif
- return MIN (align, max_align);
+ return align;
default:
return align;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d8890a0ba41..4c470541936 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-10 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/26565
+ * gcc.dg/torture/pr26565.c: New testcase.
+
2006-03-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/26499
diff --git a/gcc/testsuite/gcc.dg/torture/pr26565.c b/gcc/testsuite/gcc.dg/torture/pr26565.c
new file mode 100644
index 00000000000..9b431407f44
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr26565.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
+
+struct timeval {
+ long tv_sec;
+};
+
+struct outdata {
+ long align;
+ char seq;
+ struct timeval tv __attribute__((packed));
+};
+
+void send_probe(struct outdata *outdata, struct timeval *tp) __attribute__((noinline));
+void send_probe(struct outdata *outdata, struct timeval *tp)
+{
+ memcpy(&outdata->tv, tp, sizeof outdata->tv);
+}
+
+struct timeval t;
+struct outdata outdata;
+
+int main()
+{
+ send_probe(&outdata, &t);
+ return 0;
+}
OpenPOWER on IntegriCloud