www.digitalmars.com         C & C++   DMDScript  

D.gnu - [Bug 57] New: Comparing small structs fails

http://bugzilla.gdcproject.org/show_bug.cgi?id=57

             Bug #: 57
           Summary: Comparing small structs fails
    Classification: Unclassified
           Product: GDC
           Version: development
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: major
          Priority: Normal
         Component: gdc
        AssignedTo: ibuclaw gdcproject.org
        ReportedBy: johannespfau gmail.com


Created attachment 39
  --> http://bugzilla.gdcproject.org/attachment.cgi?id=39
test case

Comparing structs (with "==" or the "is" expression) which are small enough to
be returned in registers is currently broken under certain circumstances.

Consider this struct on a 64 bit system:
------------
struct Test //Total size 16 bytes
{
    int a;  //4 byte long
    //4 bytes of padding
    long b; //8 byte aligned, 8 byte long
}
------------

If this struct is returned from a function it is returned in registers. The
padding is not copied in that case. If the result of the function is a
temporary it is also never initialized and the padding data is undefined. GDC
then uses a simple memcmp to compare structs of this type and this fails...

DMD does not return this type in registers and therefore avoids the problem.

I'm not sure how we could solve this. If a struct is returned in registers is
something only the backend can know for sure. Is there some way to get this
information? It could be argued that the gcc backend should detect memcmps of
values which are small enough to fit into registers, but it doesn't seem to do
that right now.

Possible solutions:
* Do not return these types in registers (setting TREE_ADDRESSABLE on the
  RESULT_DECL). Problem: How to determine "these types"? How do we know if a 
  type can be returned in registers?

* Do the padding/alignment manually, therefore forcing the backend to return 
  the complete struct including padding. Problem: ugly hack, not really 
  portable, could reduce performance because of copying the padding.

* Force the backend in some other way to return the complete struct. Problem:
  Would likely need changes in gcc.

* Do not compare these types with memcmp, use member-wise comparison. Poblem: 
  What are "these types". Probably against the spec.

* Make sure all temporary values are always initialized. Problem: might need 
  changes in frontend, complicated, reduces performance as it might force types 
  out of registers

So I'm really not sure how to fix this. I'll have a look what code LDC
generates for this. But if anyone knows a good solution please tell me :-)

-- 
Configure bugmail: http://bugzilla.gdcproject.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.
May 28 2013