]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtins.c (expand_builtin_va_arg): Cope with an array-type va_list decomposing to...
authorRichard Henderson <rth@cygnus.com>
Fri, 10 Sep 1999 21:06:36 +0000 (14:06 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 10 Sep 1999 21:06:36 +0000 (14:06 -0700)
        * builtins.c (expand_builtin_va_arg): Cope with an array-type
        va_list decomposing to pointer-type.
        * rs6000.c (rs6000_va_start) Unwrap the ARRAY_TYPE to get at fields.
        (rs6000_va_arg): Likewise.

From-SVN: r29276

gcc/ChangeLog
gcc/builtins.c
gcc/config/rs6000/rs6000.c

index f174de13e198545bd385cd85d63009b15f90aac7..fc88dc39dd1207aae049ada1914e57e87e70f617 100644 (file)
@@ -1,3 +1,10 @@
+Fri Sep 10 14:04:07 1999  Richard Henderson  <rth@cygnus.com>
+
+       * builtins.c (expand_builtin_va_arg): Cope with an array-type
+       va_list decomposing to pointer-type.
+       * rs6000.c (rs6000_va_start) Unwrap the ARRAY_TYPE to get at fields.
+       (rs6000_va_arg): Likewise.
+
 Fri Sep 10 13:21:21 1999  Jim Wilson  <wilson@cygnus.com>
 
        * except.c (start_dynamic_handler): Compute size using
index ebd7b12abd80bf0c176ba989f8570d162821d36f..a77b0f860a62f92aeb649d2f055a4f22dba7937d 100644 (file)
@@ -1974,14 +1974,33 @@ expand_builtin_va_arg (valist, type)
      tree valist, type;
 {
   rtx addr, result;
-  tree promoted_type;
+  tree promoted_type, want_va_type, have_va_type;
 
-  if (TYPE_MAIN_VARIANT (TREE_TYPE (valist))
-      != TYPE_MAIN_VARIANT (va_list_type_node))
+  /* Verify that valist is of the proper type.  */
+
+  want_va_type = va_list_type_node;
+  have_va_type = TREE_TYPE (valist);
+  if (TREE_CODE (want_va_type) == ARRAY_TYPE)
+    {
+      /* If va_list is an array type, the argument may have decayed 
+        to a pointer type, e.g. by being passed to another function.
+         In that case, unwrap both types so that we can compare the
+        underlying records.  */
+      if (TREE_CODE (have_va_type) == ARRAY_TYPE
+         || TREE_CODE (have_va_type) == POINTER_TYPE)
+       {
+         want_va_type = TREE_TYPE (want_va_type);
+         have_va_type = TREE_TYPE (have_va_type);
+       }
+    }
+  if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
     {
       error ("first argument to `va_arg' not of type `va_list'");
       addr = const0_rtx;
     }
+
+  /* Generate a diagnostic for requesting data of a type that cannot
+     be passed through `...' due to type promotion at the call site.  */
   else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
     {
       const char *name = "<anonymous type>", *pname;
index 0c32c77e8958b3289b2e7895283f3543d48a4a05..edc986168e38bcc5ab6e0779678ac927ac212900 100644 (file)
@@ -1828,7 +1828,7 @@ rs6000_va_start (stdarg_p, valist, nextarg)
       return;
     }
 
-  f_gpr = TYPE_FIELDS (va_list_type_node);
+  f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
   f_fpr = TREE_CHAIN (f_gpr);
   f_ovf = TREE_CHAIN (f_fpr);
   f_sav = TREE_CHAIN (f_ovf);
@@ -1888,7 +1888,7 @@ rs6000_va_arg (valist, type)
   if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
     return std_expand_builtin_va_arg (valist, type);
 
-  f_gpr = TYPE_FIELDS (va_list_type_node);
+  f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
   f_fpr = TREE_CHAIN (f_gpr);
   f_ovf = TREE_CHAIN (f_fpr);
   f_sav = TREE_CHAIN (f_ovf);