Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

2016-02-11 Thread Matthijs van Duin via cfe-commits
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

2016-02-11 Thread Matthijs van Duin via cfe-commits
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

2016-02-11 Thread Matthijs van Duin via cfe-commits
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

2016-02-11 Thread Matthijs van Duin via cfe-commits
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

2016-02-11 Thread Matthijs van Duin via cfe-commits
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

2016-02-12 Thread Matthijs van Duin via cfe-commits
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

2016-02-19 Thread Matthijs van Duin via cfe-commits
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

2016-02-19 Thread Matthijs van Duin via cfe-commits
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

2016-02-20 Thread Matthijs van Duin via cfe-commits
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

2016-02-20 Thread Matthijs van Duin via cfe-commits
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

2016-02-20 Thread Matthijs van Duin via cfe-commits
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