aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-09-10 14:06:36 -0700
committerRichard Henderson <rth@gcc.gnu.org>1999-09-10 14:06:36 -0700
commit973a648b87fcb026397eaf72264b996cb314b8b3 (patch)
tree9ed3d0a396689339582d39fcd98a54b7395c8709 /gcc/builtins.c
parent007598f98beabc445971351a4d6c60054f089491 (diff)
downloadgcc-973a648b87fcb026397eaf72264b996cb314b8b3.zip
gcc-973a648b87fcb026397eaf72264b996cb314b8b3.tar.gz
gcc-973a648b87fcb026397eaf72264b996cb314b8b3.tar.bz2
builtins.c (expand_builtin_va_arg): Cope with an array-type va_list decomposing to pointer-type.
* 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
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ebd7b12..a77b0f8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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;