> On Jan 2, 2018, at 9:15 PM, Akira Hatanaka <ahatan...@apple.com> wrote: > > > >> On Jan 2, 2018, at 4:56 PM, Richard Smith via cfe-commits >> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote: >> >> On 2 January 2018 at 15:33, John McCall via cfe-commits >> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote: >> Hey, Richard et al. Akira and I were talking about the right ABI rule for >> deciding can-pass-in-registers-ness for structs in the presence of >> trivial_abi, and I think I like Akira's approach but wanted to get your >> input. >> >> The current definition in Itanium is: >> >> non-trivial for the purposes of calls <> >> <> >> A type is considered non-trivial for the purposes of calls if: >> >> it has a non-trivial copy constructor, move constructor, or destructor, or >> <> >> I'm assuming we're implicitly excluding deleted functions here. (I'd prefer >> to make that explicit; this has been the source of a number of ABI >> mismatches.) >> all of its copy and move constructors are deleted. >> <> >> >> I'd suggest modifying this to: >> >> A type is considered non-trivial for the purposes of calls if: >> - if has a copy constructor, move constructor, or destructor >> which is non-trivial for the purposes of calls, or >> - all of its copy and move constructors are deleted and it does >> not have the trivial_abi attribute. >> >> A copy/move constructor is considered trivial for the purposes of calls >> if: >> - it is user-provided and >> - the class has the trivial_abi attribute and >> - a defaulted definition of the constructor would be >> trivial for the purposes of calls; or >> >> We'd need to say what happens if the function in question cannot validly be >> defaulted for any of the reasons in [dcl.fct.def.default]. Do we try to >> infer whether it's a copy or move constructor, and use the rules for a >> defaulted copy or move constructor? Or do we just say that's never trivial >> for the purposes of calls? Or something else? Eg: >> >> struct [[clang::trivial_abi]] A { >> A(A && = make()); >> }; >> >> Here, A::A(A&&) cannot validly be defaulted. Is A trivial for the purpose of >> calls? Likewise: >> >> struct [[clang::trivial_abi]] B { >> B(...); >> }; >> struct C { >> volatile B b; >> }; >> >> Here, C's copy constructor calls B::B(...). Is C trivial for the purpose of >> calls? (OK, Clang crashes on that example today. But still...) >> >> I'd be uncomfortable making the rules in [dcl.fct.def.default] part of the >> ABI; they seem to be changing relatively frequently. Perhaps we could say >> "if the function is a copy constructor ([class.copy.ctor]/1), then consider >> what an implicitly-declared defaulted copy constructor would do; if it's a >> move constructor ([class.copy.ctor]/2), then consider what an >> implicitly-declared defaulted move constructor would do; otherwise, it's not >> trivial for the purpose of calls". That'd mean A is trivial for the purpose >> of calls and C is not, which I think is probably the right answer. >> >> - it is not user-provided and >> - the class has no virtual functions and no virtual >> base classes, and >> - the constructor used to copy/move each direct base >> class subobject is trivial for the purposes of calls, and >> - for each non-static data member that is of class type >> (or array thereof), the constructor selected to copy/move that member is >> trivial for the purposes of calls. >> >> A destructor is considered trivial for the purposes of calls if: >> - it is not user-provided or the class has the trivial_abi >> attribute, and >> - the destructor is not virtual, and >> - all of the direct base classes of its class have destructors >> that are trivial for the purposes of calls, and >> - for all of the non-static data members of its class that are >> of class type (or array thereof), each such class is trivial for the >> purposes of calls. >> >> These definitions are intended to follow [class.copy.ctor]p11 and >> [class.dtor]p6 except for the special rules applicable to trivial_abi >> classes. >> >> If I could rephrase: a *tor is considered trivial for for the purposes of >> calls if it is either defaulted or the class has the trivial_abi attribute, >> and the defaulted definition would satisfy the language rule for being >> trivial but with the word "trivial" replaced by "trivial for the purposes of >> calls". So only effect of the trivial_abi attribute is to "undo" the >> non-triviality implied by a user-provided *tor when computing triviality for >> the purpose of calls. >> >> I think that's a reasonable rule, if we have a satisfactory notion of >> "defaulted definition". >> >> I'm not sure about the "defaulted definition" rule for copy/move >> constructors in trivial_abi classes. The intent is to allow class temploids >> with trivial_abi that are instantiated to contain non-trivial classes to >> just silently become non-trivial. I was thinking at first that it would be >> nice to have a general rule that trivial_abi classes only contain >> trivial_abi subobjects, but unfortunately that's not consistent with the >> standard triviality rule in some silly corner cases: a trivially-copyable >> class can have a non-trivially-copyable subobject if it happens to copy that >> subobject with a trivial copy constructor. I couldn't think of a better way >> of capturing this than the "defaulted definition" rule. I considered using >> the actual initializers used by the constructor, but that would introduce a >> lot of new complexity: suddenly we'd be asking about triviality for an >> arbitrary constructor, and copy/move elision make the question somewhat >> ambiguous anyway. >> >> Per the above examples, I don't think you can escape asking about triviality >> for an arbitrary constructor if you take this path. >> >> Another option, similar to your general rule, would be to say that a type is >> considered trivial for the purpose of calls if either: (1) it is trivial for >> the purpose of calls under the current Itanium ABI rule, or (2) it has the >> trivial_abi attribute and all members and base classes have types that are >> trivial for the purpose of calls. That would sidestep the "defaulted >> definition" complexity entirely, and while it differs from the way that the >> language computes triviality normally, it doesn't seem fundamentally >> unreasonable: when we're thinking about triviality for the purpose of calls, >> there's notionally a call to the trivial copy/move ctor being elided, not a >> call to an arbitrary ctor selected by overload resolution, and we'd just be >> pushing that effect from the class itself to its subobjects with this >> attribute. >> > > It sounds like a class containing a member that has a type annotated with > “trivial_abi” would not necessarily be considered trivial for the purpose of > calls according to rule (2)? For example, S1 would not be trivial for the > purpose of calls because it isn’t annotated with “trivial_abi” in the code > below: > > struct [[clang::trivial_abi]] S0 { > // user-provided special functions declared here. > }; > > struct S1 { > S0 f0; > }; > > I thought we wanted containing classes (S1 in this case) to be trivial for > the purpose of calls too?
I would like that, yeah. John. > >> I'm also not sure about the right rules about virtual methods. Should we >> allow polymorphic classes to be made trivial by application of the attribute? >> >> I think that it probably doesn't make much sense to pass dynamic classes >> indirectly unless we can avoid passing the vptr; otherwise I'd expect we'd >> use too many registers for it to be worthwhile. Perhaps as a compromise, we >> could make the attribute ill-formed if used on a class definition that >> introduces any virtual bases or explicitly declares any member functions as >> 'virtual'. That gives us the room to make this decision later if we find we >> want to. >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits