diff options
author | Richard Henderson <rth@cygnus.com> | 1999-09-07 21:51:16 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1999-09-07 21:51:16 -0700 |
commit | c530479e15d804667c83dfb738ce9cae035de9f2 (patch) | |
tree | cc01394964ac75996779fc8fc5ebdb1781aeb69c /gcc/builtins.c | |
parent | 472236af04ca7daa01b6b5b1a00dafaf91d31f1f (diff) | |
download | gcc-c530479e15d804667c83dfb738ce9cae035de9f2.zip gcc-c530479e15d804667c83dfb738ce9cae035de9f2.tar.gz gcc-c530479e15d804667c83dfb738ce9cae035de9f2.tar.bz2 |
c-typeck.c (type_lists_compatible_p): Use simple_type_promotes_to.
* c-typeck.c (type_lists_compatible_p): Use simple_type_promotes_to.
(self_promoting_type_p): Delete.
(self_promoting_args_p): Move ...
* c-common.c: ... here.
(c_common_nodes_and_builtins): Initialize lang_type_promotes_to.
(simple_type_promotes_to): New.
* builtins.c (lang_type_promotes_to): New.
(expand_builtin_va_arg): Use it to give diagnostic for illegal types.
* c-tree.h (C_PROMOTING_INTEGER_TYPE_P): Move ...
* c-common.h: ... here.
(self_promoting_args_p, simple_type_promotes_to): Declare.
* c-decl.c (duplicate_decls): Use simple_type_promotes_to.
(grokdeclarator): Likewise.
* tree.h (lang_type_promotes_to): Declare.
* cp-tree.h (C_PROMOTING_INTEGER_TYPE_P): Delete.
* typeck.c (self_promoting_args_p): Delete.
* gcc.dg/va-arg-1.c: New.
From-SVN: r29180
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index c4e3605..ebd7b12 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -52,6 +52,8 @@ Boston, MA 02111-1307, USA. */ #define OUTGOING_REGNO(IN) (IN) #endif +tree (*lang_type_promotes_to) PROTO((tree)); + static int get_pointer_alignment PROTO((tree, unsigned)); static tree c_strlen PROTO((tree)); static rtx get_memory_rtx PROTO((tree)); @@ -1972,11 +1974,43 @@ expand_builtin_va_arg (valist, type) tree valist, type; { rtx addr, result; + tree promoted_type; if (TYPE_MAIN_VARIANT (TREE_TYPE (valist)) != TYPE_MAIN_VARIANT (va_list_type_node)) { - error ("first argument to `__builtin_va_arg' not of type `va_list'"); + error ("first argument to `va_arg' not of type `va_list'"); + addr = const0_rtx; + } + else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE) + { + const char *name = "<anonymous type>", *pname; + static int gave_help; + + if (TYPE_NAME (type)) + { + if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) + name = IDENTIFIER_POINTER (TYPE_NAME (type)); + else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL + && DECL_NAME (TYPE_NAME (type))) + name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); + } + if (TYPE_NAME (promoted_type)) + { + if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE) + pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type)); + else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL + && DECL_NAME (TYPE_NAME (promoted_type))) + pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type))); + } + + error ("`%s' is promoted to `%s' when passed through `...'", name, pname); + if (! gave_help) + { + gave_help = 1; + error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name); + } + addr = const0_rtx; } else |