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
This commit is contained in:
J"orn Rennecke 2006-02-09 20:54:12 +00:00 committed by Joern Rennecke
parent 91b4415af4
commit 11160b5817
4 changed files with 59 additions and 14 deletions

View File

@ -1,3 +1,9 @@
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> 2006-02-09 J"orn Rennecke <joern.rennecke@st.com>
PR inline-asm/16194 PR inline-asm/16194

View File

@ -6738,6 +6738,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
tree tmp, pptr_type_node; tree tmp, pptr_type_node;
tree addr, lab_over = NULL, result = NULL; tree addr, lab_over = NULL, result = NULL;
int pass_by_ref = targetm.calls.must_pass_in_stack (TYPE_MODE (type), type); int pass_by_ref = targetm.calls.must_pass_in_stack (TYPE_MODE (type), type);
tree eff_type;
if (pass_by_ref) if (pass_by_ref)
type = build_pointer_type (type); 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 /* Structures with a single member with a distinct mode are passed
like their member. This is relevant if the latter has a REAL_TYPE like their member. This is relevant if the latter has a REAL_TYPE
or COMPLEX_TYPE type. */ or COMPLEX_TYPE type. */
while (TREE_CODE (type) == RECORD_TYPE eff_type = type;
&& (member = find_sole_member (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)) == REAL_TYPE
|| TREE_CODE (TREE_TYPE (member)) == COMPLEX_TYPE || TREE_CODE (TREE_TYPE (member)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE)) || TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE))
{ {
tree field_type = TREE_TYPE (member); tree field_type = TREE_TYPE (member);
if (TYPE_MODE (type) == TYPE_MODE (field_type)) if (TYPE_MODE (eff_type) == TYPE_MODE (field_type))
type = field_type; eff_type = field_type;
else else
{ {
gcc_assert ((TYPE_ALIGN (type) gcc_assert ((TYPE_ALIGN (eff_type)
< GET_MODE_ALIGNMENT (TYPE_MODE (field_type))) < GET_MODE_ALIGNMENT (TYPE_MODE (field_type)))
|| (TYPE_ALIGN (type) || (TYPE_ALIGN (eff_type)
> GET_MODE_BITSIZE (TYPE_MODE (field_type)))); > GET_MODE_BITSIZE (TYPE_MODE (field_type))));
break; break;
} }
@ -6797,14 +6799,14 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
if (TARGET_SH4) if (TARGET_SH4)
{ {
pass_as_float = ((TREE_CODE (type) == REAL_TYPE && size <= 8) pass_as_float = ((TREE_CODE (eff_type) == REAL_TYPE && size <= 8)
|| (TREE_CODE (type) == COMPLEX_TYPE || (TREE_CODE (eff_type) == COMPLEX_TYPE
&& TREE_CODE (TREE_TYPE (type)) == REAL_TYPE && TREE_CODE (TREE_TYPE (eff_type)) == REAL_TYPE
&& size <= 16)); && size <= 16));
} }
else 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); 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 next_fp_tmp = create_tmp_var (TREE_TYPE (f_next_fp), NULL);
tree cmp; 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 = build1 (ADDR_EXPR, pptr_type_node, next_fp);
tmp = build2 (MODIFY_EXPR, void_type_node, addr, tmp); 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) if (!is_double)
gimplify_and_add (cmp, pre_p); 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 = fold_convert (ptr_type_node, size_int (UNITS_PER_WORD));
tmp = build2 (BIT_AND_EXPR, ptr_type_node, next_fp_tmp, tmp); 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); gimplify_and_add (cmp, pre_p);
#ifdef FUNCTION_ARG_SCmode_WART #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; tree real, imag;
imag imag

View File

@ -1,3 +1,8 @@
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> 2006-02-09 J"orn Rennecke <joern.rennecke@st.com>
PR inline-asm/16194 PR inline-asm/16194

View File

@ -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);
}