Bug 80178 - Class with deleted copy and move constructors uses wrong argument passing ABI
Summary: Class with deleted copy and move constructors uses wrong argument passing ABI
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.3.1
: P3 normal
Target Milestone: 8.0
Assignee: Jason Merrill
URL:
Keywords: ABI, wrong-code
Depends on:
Blocks:
 
Reported: 2017-03-24 18:09 UTC by Jonathan Wakely
Modified: 2017-05-19 18:50 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-04-04 00:00:00


Attachments
fix (3.30 KB, patch)
2017-04-05 18:57 UTC, Jason Merrill
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2017-03-24 18:09:15 UTC
We pass this in a register, but I think the ABI says it should be an invisible reference, because both the copy ctor and move ctor are deleted.

struct A {
  A();
  A &operator=(A &&o);
  void *p;
};
void foo(A);
void bar() {
  foo({});
}

In this example they're implicitly defined as deleted because of the user-provided move assignment operator, but the result is the same whether implicitly or explicitly deleted.

EDG passes this by invisible reference. Clang passes by value, but that's acknowledged to be a bug.
Comment 1 Jason Merrill 2017-03-28 16:28:55 UTC
Hmm, I don't see anything in the ABI about deleted constructors, and a deleted function isn't non-trivial (nor trivial).

That said, I agree that it makes sense for a class with only deleted copy/move ctors to be passed by invisible reference in the case of copy-list-initialization.
Comment 2 Jonathan Wakely 2017-03-28 16:58:08 UTC
This example came from a Clang discussion, and they might also be changing how they handle this. We might want to bring it up on the cxxabi list if there's any doubt what the right behaviour is.

CCing Richard, as I discussed it with him last week.
Comment 3 Jason Merrill 2017-04-05 18:57:00 UTC
Created attachment 41138 [details]
fix

Here's a fix.  I'm nervous about applying it at this point in GCC 7, though.
Comment 4 Jason Merrill 2017-05-08 19:08:39 UTC
Author: jason
Date: Mon May  8 19:08:07 2017
New Revision: 247757

URL: https://gcc.gnu.org/viewcvs?rev=247757&root=gcc&view=rev
Log:
	PR c++/80178 - parameter passing for uncopyable classes

	* tree.c (type_has_nontrivial_copy_init): True for classes with only
	deleted copy/move ctors.
	(remember_deleted_copy, maybe_warn_parm_abi): New.
	* decl.c (require_complete_types_for_parms, check_function_type):
	Call maybe_warn_parm_abi.
	* call.c (convert_for_arg_passing, build_cxx_call): Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/abi/invisiref1.C
    trunk/gcc/testsuite/g++.dg/abi/invisiref1a.C
Modified:
    trunk/gcc/common.opt
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/call.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/tree.c
Comment 5 Jason Merrill 2017-05-19 18:50:09 UTC
Fixed for gcc 8.