Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 8 February 2016 at 22:40, H.J. Lu wrote: > "empty type". An empty type is either an array of empty types or a > class type where every member is of empty type. Note that the term "empty type" is commonly used in type theory to denote a (or the) type with no values. The closest thing C has would be an empty enum when using -fstrict-enums. (Declaring it as return type implies [[noreturn]] or undefined behaviour.) A type with a unique value (such as void or an empty struct) is usually known as a unit type. BTW, being standard layout is not sufficient (nor required afaict) for zero-register passing of a unit type. The requirement you need is trivially-copyable. Example: #include #include #include using namespace std; class EmptyInt { static map< const EmptyInt *, int > values; public: EmptyInt() = default; EmptyInt( int x ) { values[this] = x; } ~EmptyInt() { values.erase(this); } operator int () const { return values[this]; } }; typeof( EmptyInt::values ) EmptyInt::values; EmptyInt foo() { return 42; } int main() { cout << is_standard_layout{} << endl; cout << foo() << endl; return 0; } This evil contraption satisfies all POD-requirements except for not being trivially-copyable. On the other hand taking this example from http://en.cppreference.com/w/cpp/concept/StandardLayoutType struct Q {}; struct S : Q {}; struct T : Q {}; struct U : S, T {}; // not a standard-layout class Even though U is not standard-layout, it is trivially-copyable and I see no reason to allocate a register to pass it. Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 11 February 2016 at 11:53, H.J. Lu wrote: > Since this isn't Plain Old Data (POD) for the purposes of layout, it > isn't covered by my proposal for psABI. I leave this to C++ ABI. You never define "POD for the purposes of layout", and I can only interpret it as being equivalent to "standard-layout". The property of being trivially copyable/destructible is not a statement about layout and my EmptyInt example is POD in every other aspect. There's a good argument for trivially copyable/destructible being the relevant property: it means an object can be copied simply by copying its bytes and destroyed simply by discarding its storage. If the object occupies no storage (other than padding) then these operations become nops hence there is never a need to have a pointer/reference to the original object. The precise layout is not really important here, e.g. struct U is unusually large considering its lack of data members, due to the need for padding between its base classes, but this doesn't change the fact it can be copied using no operation (and g++ indeed does). Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 11 February 2016 at 13:58, H.J. Lu wrote: > "POD for the purpose of layout" is defined in the Itanium C++ ABI here: > > http://mentorembedded.github.io/cxx-abi/abi.html#definitions Sorry, I overlooked that. I still stand by my viewpoint however that triviality of copying and destruction is the appropriate criterion here rather than this obscure constraint on layout. Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 11 February 2016 at 15:00, H.J. Lu wrote: > I intentionally exclude C++ specific features in my propose. Yet you use a definition from the Itanium C++ ABI which itself depends on multiple definitions in a particular version of the C++ standard, which depend on C++ specific features. This makes no sense to me. Note that triviality of copying/destruction holds for all C types and is easy to formulate in languages other than C++. (As is the notion of an aggregate requiring no storage, other than padding. The whole argument about array parameters seems a bit silly since this is mere syntax sugar, C/C++ do not support passing an actual array by value.) Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
To avoid depending again on precise wording of definitions in C++ standard it may be worth being explicit about the requirement to be trivially copyable *and* destructible, since although the former implies the latter in the C++ standard this is not obvious from the terminology (although you also need the latter in all practical cases including the one being discussed). The explanation I gave earlier ("it means an object can be copied simply by copying its bytes and destroyed simply by discarding its storage") can probably be polished into a language-agnostic definition. I think it is helpful in general when ABI standards can be extended to other languages with as much ease and unambiguity as possible, for the sake of interoperability. For similar reasons I would support "aggregate occupying zero bytes (excluding any padding)" with a footnote on the strange situation of C/C++ arrays, which cannot be directly passed by value even if the syntax may suggest they can (hence the rule being discussed is not applicable to them). Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 11 February 2016 at 16:31, H.J. Lu wrote: > struct A { > static void foo (void) (); > static int xxx; > }; What about it? It's an empty struct. (And it declares a function and a variable in the namespace of A, which however do not have any relevant impact here.) Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 19 February 2016 at 16:27, H.J. Lu wrote: > We want to include static member functions and exclude non-static member > functions. > There's no reason to disallow non-static member functions in general; they have no impact on being trivially copyable or not, only the presence of a non-trivial copy constructor or destructor does. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 19 February 2016 at 14:35, Michael Matz wrote: > struct S { > S() {something();} > }; > > would be an empty type, and that's not what we want. Why not? The default constructor is never invoked as part of passing such an object around. Its copy constructor is a nop and requires no reference to the original object. Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 20 February 2016 at 18:55, H.J. Lu wrote: > struct dummy0 > { > }; > > struct dummy > { > dummy0 d[20]; > > dummy0 * foo (int i); > }; > > dummy0 * > dummy::foo (int i) > { > return &d[i]; > } > > dummy0 * > bar (dummy d, int i) > { > return d.foo (i); > } 1. This has undefined behaviour due to returning a pointer to a local variable 2. There's still no need for the reference to the original argument since copying it is a nop. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 20 February 2016 at 20:34, H.J. Lu wrote: > Is there a class, which meets the above definition, with a member function > which can't be passed without a memory slot or a register? The EmptyInt class in my first post in this thread. It has no non-static data members, has standard layout, and has a trivial default constructor, but it has a non-trivial copy constructor and non-trivial destructor. Matthijs van Duin ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct
On 20 February 2016 at 23:35, H.J. Lu wrote: > Can a compiler tell if a copy constructor or destructor is trivial > from the class declaration without function body? Yes, the mere presence of the declaration suffices to render it non-trivial (unless explicitly declared "= default" like I did with the default constructor, in which case there's no function body). ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits