From: Richard Henderson Date: Fri, 10 Sep 1999 21:06:36 +0000 (-0700) Subject: builtins.c (expand_builtin_va_arg): Cope with an array-type va_list decomposing to... X-Git-Tag: prereleases/libstdc++-2.92~10675 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=973a648b87fcb026397eaf72264b996cb314b8b3;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f174de13e198..fc88dc39dd12 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Fri Sep 10 14:04:07 1999 Richard Henderson + + * 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 * except.c (start_dynamic_handler): Compute size using diff --git a/gcc/builtins.c b/gcc/builtins.c index ebd7b12abd80..a77b0f860a62 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 = "", *pname; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0c32c77e8958..edc986168e38 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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);