aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-09-07 21:51:16 -0700
committerRichard Henderson <rth@gcc.gnu.org>1999-09-07 21:51:16 -0700
commitc530479e15d804667c83dfb738ce9cae035de9f2 (patch)
treecc01394964ac75996779fc8fc5ebdb1781aeb69c /gcc/c-common.c
parent472236af04ca7daa01b6b5b1a00dafaf91d31f1f (diff)
downloadgcc-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/c-common.c')
-rw-r--r--gcc/c-common.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 4fea4ac..3de1e92 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -3804,6 +3804,10 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
NULL_PTR);
#endif
+
+ /* ??? Perhaps there's a better place to do this. But it is related
+ to __builtin_va_arg, so it isn't that off-the-wall. */
+ lang_type_promotes_to = simple_type_promotes_to;
}
tree
@@ -3967,4 +3971,58 @@ initializer_constant_valid_p (value, endtype)
return 0;
}
+
+/* Given a type, apply default promotions wrt unnamed function arguments
+ and return the new type. Return NULL_TREE if no change. */
+/* ??? There is a function of the same name in the C++ front end that
+ does something similar, but is more thorough and does not return NULL
+ if no change. We could perhaps share code, but it would make the
+ self_promoting_type property harder to identify. */
+
+tree
+simple_type_promotes_to (type)
+ tree type;
+{
+ if (TYPE_MAIN_VARIANT (type) == float_type_node)
+ return double_type_node;
+
+ if (C_PROMOTING_INTEGER_TYPE_P (type))
+ {
+ /* Traditionally, unsignedness is preserved in default promotions.
+ Also preserve unsignedness if not really getting any wider. */
+ if (TREE_UNSIGNED (type)
+ && (flag_traditional
+ || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
+ return unsigned_type_node;
+ return integer_type_node;
+ }
+
+ return NULL_TREE;
+}
+
+/* Return 1 if PARMS specifies a fixed number of parameters
+ and none of their types is affected by default promotions. */
+
+int
+self_promoting_args_p (parms)
+ tree parms;
+{
+ register tree t;
+ for (t = parms; t; t = TREE_CHAIN (t))
+ {
+ register tree type = TREE_VALUE (t);
+ if (TREE_CHAIN (t) == 0 && type != void_type_node)
+ return 0;
+
+ if (type == 0)
+ return 0;
+
+ if (TYPE_MAIN_VARIANT (type) == float_type_node)
+ return 0;
+
+ if (C_PROMOTING_INTEGER_TYPE_P (type))
+ return 0;
+ }
+ return 1;
+}