diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-08-13 18:25:06 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-08-13 18:25:06 +0000 |
commit | 7dab9307f1670e455f9c3f06034c857710c93d5d (patch) | |
tree | 5e22cf22a1c702b54fc7df06c5a5de3bb7039526 /gcc/cp/call.c | |
parent | f50214f368949c9b317998ad1af88ad8fb50f9c1 (diff) | |
download | gcc-7dab9307f1670e455f9c3f06034c857710c93d5d.tar.gz |
* call.c (build_x_va_arg): Support passing non-POD through ....
(convert_arg_to_ellipsis): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213921 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 64cab453ae0..43bfe504d21 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6570,8 +6570,8 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) with no corresponding parameter is conditionally-supported, with implementation-defined semantics. - We used to just warn here and do a bitwise copy, but now - cp_expr_size will abort if we try to do that. + We support it as pass-by-invisible-reference, just like a normal + value parameter. If the call appears in the context of a sizeof expression, it is not potentially-evaluated. */ @@ -6579,10 +6579,12 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) && (type_has_nontrivial_copy_init (arg_type) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type))) { - if (complain & tf_error) - error_at (loc, "cannot pass objects of non-trivially-copyable " - "type %q#T through %<...%>", arg_type); - return error_mark_node; + if (complain & tf_warning) + warning (OPT_Wconditionally_supported, + "passing objects of non-trivially-copyable " + "type %q#T through %<...%> is conditionally supported", + arg_type); + return cp_build_addr_expr (arg, complain); } } @@ -6595,7 +6597,11 @@ tree build_x_va_arg (source_location loc, tree expr, tree type) { if (processing_template_decl) - return build_min (VA_ARG_EXPR, type, expr); + { + tree r = build_min (VA_ARG_EXPR, type, expr); + SET_EXPR_LOCATION (r, loc); + return r; + } type = complete_type_or_else (type, NULL_TREE); @@ -6604,18 +6610,24 @@ build_x_va_arg (source_location loc, tree expr, tree type) expr = mark_lvalue_use (expr); + if (TREE_CODE (type) == REFERENCE_TYPE) + { + error ("cannot receive reference type %qT through %<...%>", type); + return error_mark_node; + } + if (type_has_nontrivial_copy_init (type) - || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) - || TREE_CODE (type) == REFERENCE_TYPE) - { - /* Remove reference types so we don't ICE later on. */ - tree type1 = non_reference (type); - /* conditionally-supported behavior [expr.call] 5.2.2/7. */ - error ("cannot receive objects of non-trivially-copyable type %q#T " - "through %<...%>; ", type); - expr = convert (build_pointer_type (type1), null_node); - expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error); - return expr; + || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) + { + /* conditionally-supported behavior [expr.call] 5.2.2/7. Let's treat + it as pass by invisible reference. */ + warning_at (loc, OPT_Wconditionally_supported, + "receiving objects of non-trivially-copyable type %q#T " + "through %<...%> is conditionally-supported", type); + + tree ref = cp_build_reference_type (type, false); + expr = build_va_arg (loc, expr, ref); + return convert_from_reference (expr); } return build_va_arg (loc, expr, type); |