diff options
author | J"orn Rennecke <joern.rennecke@st.com> | 2006-02-09 20:54:12 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2006-02-09 20:54:12 +0000 |
commit | 11160b5817b5ff284e34a2810ac39d871aa0d93b (patch) | |
tree | 189320c000b05f1164943a1fd6d56dc5d0f30d9b | |
parent | 91b4415af4fafcd53f44b671003e917dd7ec0cfd (diff) | |
download | gcc-11160b5817b5ff284e34a2810ac39d871aa0d93b.zip gcc-11160b5817b5ff284e34a2810ac39d871aa0d93b.tar.gz gcc-11160b5817b5ff284e34a2810ac39d871aa0d93b.tar.bz2 |
re PR target/26141 (va_arg causes cc1plus ICE in gimplify_addr_expr)
PR target/26141
gcc:
* sh.c (sh_gimplify_va_arg_expr): Don't change the result type when
computing the effective result type.
gcc/testsuite:
* g++.dg/expr/stdarg2.C: New test.
From-SVN: r110811
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/stdarg2.C | 30 |
4 files changed, 59 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 763e081..bec2374 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2006-02-09 J"orn Rennecke <joern.rennecke@st.com> + PR target/26141 + * sh.c (sh_gimplify_va_arg_expr): Don't change the result type when + computing the effective result type. + +2006-02-09 J"orn Rennecke <joern.rennecke@st.com> + PR inline-asm/16194 * tree.h (decl_overlaps_hard_reg_set_p) Don't declare. (tree_overlaps_hard_reg_set): Declare. diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 056b32b..237da26 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6738,6 +6738,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree tmp, pptr_type_node; tree addr, lab_over = NULL, result = NULL; int pass_by_ref = targetm.calls.must_pass_in_stack (TYPE_MODE (type), type); + tree eff_type; if (pass_by_ref) type = build_pointer_type (type); @@ -6775,21 +6776,22 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, /* Structures with a single member with a distinct mode are passed like their member. This is relevant if the latter has a REAL_TYPE or COMPLEX_TYPE type. */ - while (TREE_CODE (type) == RECORD_TYPE - && (member = find_sole_member (type)) + eff_type = type; + while (TREE_CODE (eff_type) == RECORD_TYPE + && (member = find_sole_member (eff_type)) && (TREE_CODE (TREE_TYPE (member)) == REAL_TYPE || TREE_CODE (TREE_TYPE (member)) == COMPLEX_TYPE || TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE)) { tree field_type = TREE_TYPE (member); - if (TYPE_MODE (type) == TYPE_MODE (field_type)) - type = field_type; + if (TYPE_MODE (eff_type) == TYPE_MODE (field_type)) + eff_type = field_type; else { - gcc_assert ((TYPE_ALIGN (type) + gcc_assert ((TYPE_ALIGN (eff_type) < GET_MODE_ALIGNMENT (TYPE_MODE (field_type))) - || (TYPE_ALIGN (type) + || (TYPE_ALIGN (eff_type) > GET_MODE_BITSIZE (TYPE_MODE (field_type)))); break; } @@ -6797,14 +6799,14 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, if (TARGET_SH4) { - pass_as_float = ((TREE_CODE (type) == REAL_TYPE && size <= 8) - || (TREE_CODE (type) == COMPLEX_TYPE - && TREE_CODE (TREE_TYPE (type)) == REAL_TYPE + pass_as_float = ((TREE_CODE (eff_type) == REAL_TYPE && size <= 8) + || (TREE_CODE (eff_type) == COMPLEX_TYPE + && TREE_CODE (TREE_TYPE (eff_type)) == REAL_TYPE && size <= 16)); } else { - pass_as_float = (TREE_CODE (type) == REAL_TYPE && size == 4); + pass_as_float = (TREE_CODE (eff_type) == REAL_TYPE && size == 4); } addr = create_tmp_var (pptr_type_node, NULL); @@ -6817,7 +6819,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, { tree next_fp_tmp = create_tmp_var (TREE_TYPE (f_next_fp), NULL); tree cmp; - bool is_double = size == 8 && TREE_CODE (type) == REAL_TYPE; + bool is_double = size == 8 && TREE_CODE (eff_type) == REAL_TYPE; tmp = build1 (ADDR_EXPR, pptr_type_node, next_fp); tmp = build2 (MODIFY_EXPR, void_type_node, addr, tmp); @@ -6836,7 +6838,8 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, if (!is_double) gimplify_and_add (cmp, pre_p); - if (TYPE_ALIGN (type) > BITS_PER_WORD || (is_double || size == 16)) + if (TYPE_ALIGN (eff_type) > BITS_PER_WORD + || (is_double || size == 16)) { tmp = fold_convert (ptr_type_node, size_int (UNITS_PER_WORD)); tmp = build2 (BIT_AND_EXPR, ptr_type_node, next_fp_tmp, tmp); @@ -6848,9 +6851,10 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, gimplify_and_add (cmp, pre_p); #ifdef FUNCTION_ARG_SCmode_WART - if (TYPE_MODE (type) == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN) + if (TYPE_MODE (eff_type) == SCmode + && TARGET_SH4 && TARGET_LITTLE_ENDIAN) { - tree subtype = TREE_TYPE (type); + tree subtype = TREE_TYPE (eff_type); tree real, imag; imag diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 59778df..f53188f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2006-02-09 J"orn Rennecke <joern.rennecke@st.com> + PR target/26141 + * g++.dg/expr/stdarg2.C: New test. + +2006-02-09 J"orn Rennecke <joern.rennecke@st.com> + PR inline-asm/16194 * gcc.dg/pr16194.c: New test. diff --git a/gcc/testsuite/g++.dg/expr/stdarg2.C b/gcc/testsuite/g++.dg/expr/stdarg2.C new file mode 100644 index 0000000..cf2eabc --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/stdarg2.C @@ -0,0 +1,30 @@ +// PR target/26141 + +#include <stdarg.h> + +struct S +{ + double a; +}; + +void +foo (int z, ...) +{ + struct S arg; + va_list ap; + arg = va_arg (ap, struct S); +} + + +struct T +{ + __complex__ float a; +}; + +void +bar (int z, ...) +{ + struct T arg; + va_list ap; + arg = va_arg (ap, struct T); +} |