+ if (param_type == NULL)
+ continue;
+
+ auto info = language_pass_by_reference (param_type);
+ if (!info.copy_constructible)
+ error (_("expression cannot be evaluated because the type '%s' "
+ "is not copy constructible"), TYPE_NAME (param_type));
+
+ if (!info.destructible)
+ error (_("expression cannot be evaluated because the type '%s' "
+ "is not destructible"), TYPE_NAME (param_type));
+
+ if (info.trivially_copyable)
+ continue;
+
+ /* Make a copy of the argument on the stack. If the argument is
+ trivially copy ctor'able, copy bit by bit. Otherwise, call
+ the copy ctor to initialize the clone. */
+ CORE_ADDR addr = reserve_stack_space (param_type, sp);
+ value *clone
+ = value_from_contents_and_address (param_type, nullptr, addr);
+ push_thread_stack_temporary (call_thread.get (), clone);
+ value *clone_ptr
+ = value_from_pointer (lookup_pointer_type (param_type), addr);
+
+ if (info.trivially_copy_constructible)
+ {
+ int length = TYPE_LENGTH (param_type);
+ write_memory (addr, value_contents (args[i]), length);
+ }
+ else
+ {
+ value *copy_ctor;
+ value *cctor_args[2] = { clone_ptr, original_arg };
+ find_overload_match (gdb::make_array_view (cctor_args, 2),
+ TYPE_NAME (param_type), METHOD,
+ &clone_ptr, nullptr, ©_ctor, nullptr,
+ nullptr, 0, EVAL_NORMAL);
+
+ if (copy_ctor == nullptr)
+ error (_("expression cannot be evaluated because a copy "
+ "constructor for the type '%s' could not be found "
+ "(maybe inlined?)"), TYPE_NAME (param_type));
+
+ call_function_by_hand (copy_ctor, default_return_type,
+ gdb::make_array_view (cctor_args, 2));
+ }
+
+ /* If the argument has a destructor, remember it so that we
+ invoke it after the infcall is complete. */
+ if (!info.trivially_destructible)
+ {
+ /* Looking up the function via overload resolution does not
+ work because the compiler (in particular, gcc) adds an
+ artificial int parameter in some cases. So we look up
+ the function by using the "~" name. This should be OK
+ because there can be only one dtor definition. */
+ const char *dtor_name = nullptr;
+ for (int fieldnum = 0;
+ fieldnum < TYPE_NFN_FIELDS (param_type);
+ fieldnum++)
+ {
+ fn_field *fn
+ = TYPE_FN_FIELDLIST1 (param_type, fieldnum);
+ const char *field_name
+ = TYPE_FN_FIELDLIST_NAME (param_type, fieldnum);
+
+ if (field_name[0] == '~')
+ dtor_name = TYPE_FN_FIELD_PHYSNAME (fn, 0);
+ }
+
+ if (dtor_name == nullptr)
+ error (_("expression cannot be evaluated because a destructor "
+ "for the type '%s' could not be found "
+ "(maybe inlined?)"), TYPE_NAME (param_type));
+
+ value *dtor
+ = find_function_in_inferior (dtor_name, 0);
+
+ /* Insert the dtor to the front of the list to call them
+ in reverse order later. */
+ dtors_to_invoke.emplace_front (dtor, clone_ptr);
+ }
+
+ args[i] = clone_ptr;