diff options
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 107 |
1 files changed, 5 insertions, 102 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 687e7bd..ed23490 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -214,8 +214,6 @@ static void add_candidates (tree, tree, const vec<tree, va_gc> *, tree, tree, tsubst_flags_t); static conversion *merge_conversion_sequences (conversion *, conversion *); static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); -static bool pass_as_empty_struct (tree type); -static tree empty_class_arg (tree); /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE. NAME can take many forms... */ @@ -381,31 +379,16 @@ build_call_a (tree function, int n, tree *argarray) /* Don't pass empty class objects by value. This is useful for tags in STL, which are used to control overload resolution. We don't need to handle other cases of copying empty classes. */ - bool warned = false; - if (decl && !TREE_PUBLIC (decl)) - /* Don't warn about the ABI of a function local to this TU. */ - warned = true; - tree empty_arg = NULL_TREE; if (! decl || ! DECL_BUILT_IN (decl)) for (i = 0; i < n; i++) { tree arg = CALL_EXPR_ARG (function, i); - tree type = TREE_TYPE (arg); - if (is_really_empty_class (type) - && ! TREE_ADDRESSABLE (type)) + if (is_empty_class (TREE_TYPE (arg)) + && ! TREE_ADDRESSABLE (TREE_TYPE (arg))) { - empty_arg = arg; - CALL_EXPR_ARG (function, i) = empty_class_arg (arg); - } - /* Warn about ABI changes for a non-final argument. */ - else if (!warned && empty_arg) - { - location_t loc = EXPR_LOC_OR_LOC (empty_arg, input_location); - if (decl && !varargs_function_p (decl)) - mark_for_abi_warning (decl, empty_arg); - else - warn_empty_class_abi (empty_arg, loc); - warned = true; + tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (arg)); + arg = build2 (COMPOUND_EXPR, TREE_TYPE (t), arg, t); + CALL_EXPR_ARG (function, i) = arg; } } @@ -6889,15 +6872,6 @@ build_x_va_arg (source_location loc, tree expr, tree type) expr = build_va_arg (loc, expr, ref); return convert_from_reference (expr); } - else if (is_really_empty_class (type) && !TREE_ADDRESSABLE (type)) - { - /* Do the reverse of empty_class_arg. */ - tree etype = pass_as_empty_struct (type) ? empty_struct_type : type; - expr = build_va_arg (loc, expr, etype); - warn_empty_class_abi (type, loc); - tree ec = build0 (EMPTY_CLASS_EXPR, type); - return build2 (COMPOUND_EXPR, type, expr, ec); - } return build_va_arg (loc, expr, type); } @@ -6994,75 +6968,6 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum, return arg; } -/* Return true iff TYPE should be passed and returned as a size 0 type rather - than its normal size, for compatibility with C. */ - -static bool -pass_as_empty_struct (tree type) -{ - return (abi_version_at_least (10) - && type != error_mark_node - && COMPLETE_TYPE_P (type) - && !TREE_ADDRESSABLE (type) - && is_really_empty_class (type)); -} - -/* Adjust the value VAL of empty class type TYPE for argument passing. - Keep this synced with build_x_va_arg. */ - -static tree -empty_class_arg (tree val) -{ - /* Don't pass empty class objects by value. This is useful - for tags in STL, which are used to control overload resolution. - We don't need to handle other cases of copying empty classes. */ - tree type = TREE_TYPE (val); - tree etype = pass_as_empty_struct (type) ? empty_struct_type : type; - tree empty = build0 (EMPTY_CLASS_EXPR, etype); - return build2 (COMPOUND_EXPR, etype, val, empty); -} - -/* Generate a message warning about the change in empty class parameter passing - ABI. */ - -static tree -empty_class_msg (tree type) -{ - if (!TYPE_P (type)) - type = TREE_TYPE (type); - - return pp_format_to_string ("empty class %qT parameter passing ABI " - "changes in -fabi-version=10 (GCC 6)", type); -} - -/* Warn immediately about the change in empty class parameter ABI. */ - -void -warn_empty_class_abi (tree arg, location_t loc) -{ - if (!warn_abi || !abi_version_crosses (10)) - return; - - warning_at (loc, OPT_Wabi, "%E", empty_class_msg (arg)); -} - -/* Tack a warning about the change in empty class parameter ABI onto FN, so - that we get a warning if a definition or call is emitted. */ - -void -mark_for_abi_warning (tree fn, tree type) -{ - if (!warn_abi || !abi_version_crosses (10)) - return; - if (lookup_attribute ("abi warning", DECL_ATTRIBUTES (fn))) - return; - - tree msg = empty_class_msg (type); - msg = build_tree_list (NULL_TREE, msg); - DECL_ATTRIBUTES (fn) = tree_cons (get_identifier ("abi warning"), msg, - DECL_ATTRIBUTES (fn)); -} - /* Returns the type which will really be used for passing an argument of type TYPE. */ @@ -7081,8 +6986,6 @@ type_passed_as (tree type) && COMPLETE_TYPE_P (type) && tree_int_cst_lt (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) type = integer_type_node; - else if (pass_as_empty_struct (type)) - type = empty_struct_type; return type; } |