diff options
author | Richard Henderson <rth@cygnus.com> | 1999-09-10 14:06:36 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1999-09-10 14:06:36 -0700 |
commit | 973a648b87fcb026397eaf72264b996cb314b8b3 (patch) | |
tree | 9ed3d0a396689339582d39fcd98a54b7395c8709 /gcc/builtins.c | |
parent | 007598f98beabc445971351a4d6c60054f089491 (diff) | |
download | gcc-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.c | 25 |
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; |