From 356955cfb5f78224bc8c6d085d02d904ba84b4aa Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 13 Oct 1999 08:49:54 +0000 Subject: [PATCH] cp-tree.h (build_x_va_arg): Prototype new function. * cp-tree.h (build_x_va_arg): Prototype new function. * call.c (build_x_va_arg): Define it. * parse.y (unary_expr): Call build_x_va_arg. * cp-tree.h (convert_type_from_ellipsis): Prototype new function. * call.c (convert_type_from_ellipsis): Define it. * decl.c (init_decl_processing): Set lang_type_promotes_to. * tree.c (lvalue_p_1): Accept VA_ARG_EXPR with aggregates. From-SVN: r29942 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/call.c | 42 ++++++++++++++++++++++++++++++++++++++++++ gcc/cp/cp-tree.h | 2 ++ gcc/cp/decl.c | 1 + gcc/cp/parse.y | 2 +- gcc/cp/tree.c | 1 + 6 files changed, 59 insertions(+), 1 deletion(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 59e0932ec1f..9bb81d02fb7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +1999-10-13 Nathan Sidwell + + * cp-tree.h (build_x_va_arg): Prototype new function. + * call.c (build_x_va_arg): Define it. + * parse.y (unary_expr): Call build_x_va_arg. + + * cp-tree.h (convert_type_from_ellipsis): Prototype new function. + * call.c (convert_type_from_ellipsis): Define it. + * decl.c (init_decl_processing): Set lang_type_promotes_to. + + * tree.c (lvalue_p_1): Accept VA_ARG_EXPR with aggregates. + 1999-10-11 Jason Merrill * class.c (fixed_type_or_null): Always set *nonnull. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6eaf61e77fe..dd4e44246f8 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3813,6 +3813,48 @@ convert_arg_to_ellipsis (arg) return arg; } +/* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused. */ + +tree +build_x_va_arg (expr, type) + tree expr; + tree type; +{ + type = complete_type_or_else (type, NULL_TREE); + + if (expr == error_mark_node || !type) + return error_mark_node; + + if (! pod_type_p (type)) + { + /* Undefined behaviour [expr.call] 5.2.2/7. */ + cp_warning ("cannot receive objects of non-POD type `%#T' through `...'", + type); + } + + return build_va_arg (expr, type); +} + +/* TYPE has been given to va_arg. Apply the default conversions which would + have happened when passed via ellipsis. Return the promoted type, or + NULL_TREE, if there is no change. */ + +tree +convert_type_from_ellipsis (type) + tree type; +{ + tree promote; + + if (TREE_CODE (type) == ARRAY_TYPE) + promote = build_pointer_type (TREE_TYPE (type)); + else if (TREE_CODE (type) == FUNCTION_TYPE) + promote = build_pointer_type (type); + else + promote = type_promotes_to (type); + + return same_type_p (type, promote) ? NULL_TREE : promote; +} + /* ARG is a default argument expression being passed to a parameter of the indicated TYPE, which is a parameter to FN. Do any required conversions. Return the converted value. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 82ed8824a8b..3246e5af875 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3270,6 +3270,8 @@ extern int can_convert_arg PROTO((tree, tree, tree)); extern int enforce_access PROTO((tree, tree)); extern tree convert_default_arg PROTO((tree, tree, tree)); extern tree convert_arg_to_ellipsis PROTO((tree)); +extern tree build_x_va_arg PROTO((tree, tree)); +extern tree convert_type_from_ellipsis PROTO((tree)); extern int is_properly_derived_from PROTO((tree, tree)); extern tree initialize_reference PROTO((tree, tree)); extern tree strip_top_quals PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1554abc6df4..60dac525eb5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6221,6 +6221,7 @@ init_decl_processing () = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST)); c_common_nodes_and_builtins (1, flag_no_builtin, flag_no_nonansi_builtin); + lang_type_promotes_to = convert_type_from_ellipsis; void_ftype_ptr = build_exception_variant (void_ftype_ptr, empty_except_spec); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index e9d8068e388..335c022627a 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -1173,7 +1173,7 @@ unary_expr: | IMAGPART cast_expr %prec UNARY { $$ = build_x_unary_op (IMAGPART_EXPR, $2); } | VA_ARG '(' expr_no_commas ',' type_id ')' - { $$ = build_va_arg ($3, groktypename ($5.t)); + { $$ = build_x_va_arg ($3, groktypename ($5.t)); check_for_new_type ("__builtin_va_arg", $5); } ; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index b27f9c8fc90..0b5f84365d5 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -145,6 +145,7 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) return treat_class_rvalues_as_lvalues ? clk_class : clk_none; case CALL_EXPR: + case VA_ARG_EXPR: return ((treat_class_rvalues_as_lvalues && IS_AGGR_TYPE (TREE_TYPE (ref))) ? clk_class : clk_none);