diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-08 04:51:16 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-08 04:51:16 +0000 |
commit | e94026dabe3924024adfc34b810069417f75c5d1 (patch) | |
tree | cc01394964ac75996779fc8fc5ebdb1781aeb69c /gcc/builtins.c | |
parent | 532166a82e0a78a1e9add8f06eb5f6d8e71bc769 (diff) | |
download | ppe42-gcc-e94026dabe3924024adfc34b810069417f75c5d1.tar.gz ppe42-gcc-e94026dabe3924024adfc34b810069417f75c5d1.zip |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29180 138bc75d-0d04-0410-961f-82ee72b054a4
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 c4e36059d07..ebd7b12abd8 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 |