re PR target/26141 (va_arg causes cc1plus ICE in gimplify_addr_expr)
authorJ"orn Rennecke <joern.rennecke@st.com>
Thu, 9 Feb 2006 20:54:12 +0000 (20:54 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Thu, 9 Feb 2006 20:54:12 +0000 (20:54 +0000)
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

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/stdarg2.C [new file with mode: 0644]

index 763e081d178d92c8fe2de05d9ae320b6db8da5d0..bec237477ad8875ed92b3cf756328710e64fa53b 100644 (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>
 
        PR inline-asm/16194
index 056b32b2c426b04fc3e66e1644d72fe289665030..237da2619e7dae57f8581adc61e22105574e3321 100644 (file)
@@ -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
index 59778df2f870c19d2346ce7ea9c0ac6f280fdd8e..f53188f5c9f12a6577ba45ffc8afd095f517dc80 100644 (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>
 
        PR inline-asm/16194
diff --git a/gcc/testsuite/g++.dg/expr/stdarg2.C b/gcc/testsuite/g++.dg/expr/stdarg2.C
new file mode 100644 (file)
index 0000000..cf2eabc
--- /dev/null
@@ -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);
+}