www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3914] New: Struct as argument that fits in register has member accessed wrong

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3914

           Summary: Struct as argument that fits in register has member
                    accessed wrong
           Product: D
           Version: 2.041
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: crimson.magus gmail.com


--- Comment #0 from Aldo Nunez <crimson.magus gmail.com> 2010-03-09 10:54:31
PST ---
Depending on the build options and where in a function the struct parameter is
used, referencing one member will actually reference another one.

Given the following program:

import std.stdio;

struct SS
{
    char a;
    char b;
    char c;
    char d;
//    char e;
}

void A( SS ss1 )
{
C:    //writeln( ss1.a, ss1.b, ss1.c, ss1.d );

    char temp;

    temp = ss1.a;
    ss1.a = ss1.d;
    ss1.d = temp;

    temp = ss1.b;
    ss1.b = ss1.c;
    ss1.c = temp;

B:    //writeln( ss1.a, ss1.b, ss1.c, ss1.d );

    temp = ss1.a;
    ss1.a = ss1.d;
    ss1.d = temp;

    temp = ss1.b;
    ss1.b = ss1.c;
    ss1.c = temp;

A:    writeln( ss1.a, ss1.b, ss1.c, ss1.d );
}

void main()
{
    SS ss3;

    ss3.a = 'A';
    ss3.b = 'L';
    ss3.c = 'D';
    ss3.d = 'O';

    A( ss3 );
}

If lines A, B, and C are enabled in the following pattern along with the given
build options, you get these results:

    (none)    -g    -rel    -rel-O    -O    -g -O
A    ALDO    ALDO    ALDO    ALDA    ALDA    ALDA

B, A    ODLA    ODLA    ODLA    ADLA    ADLA    ADLA
    ALDO    ALDO    ALDO    ALDA    ALDA    ALDA

C, B, A    ALDA    ALDO    ALDA    ALDA    ALDA    ALDA
    ODLA    ODLA    ODLA    ODLA    ODLA    ODLA
    ALDO    ALDO    ALDO    ALDO    ALDO    ALDO

In particular, notice that field 'd' starts off wrong.
If I uncomment field 'e', or change one of them to an int, the problem goes
away.

At C, "ALDO" should be printed.
At B, "ODLA" should be printed.
At A, "ALDO" should be printed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 09 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3914


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au
           Severity|normal                      |critical


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3914



--- Comment #1 from Don <clugdbug yahoo.com.au> 2010-03-11 12:51:37 PST ---
Here's a slightly reduced test case which doesn't require any compiler flags. 
Not a regression, fails even on DMD0.165.
It's a problem with variadic function parameters and fastpar arguments.
------------
struct SS {
    char a, b, c, d;
}

void show(char[] args...) {
    assert(args[0]=='A');
    assert(args[1]=='L');
    assert(args[2]=='D');
    assert(args[3]=='O');
}

void A( SS ss ) {
    show( ss.a, ss.b, ss.c, ss.d );
}

void main(){
    SS ss3;
    ss3.a = 'A';
    ss3.b = 'L';
    ss3.c = 'D';
    ss3.d = 'O';
    A( ss3 );
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 11 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3914


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #2 from Don <clugdbug yahoo.com.au> 2010-03-12 05:51:40 PST ---
PATCH: The struct ss is passed in EAX. The backend wants ss.b. It sees that
ss.b is already in EAX, so it doesn't reload it into AX. But AX actually
contains ss.a.
Solution: Disable the optimisation in cod1.loaddata() if it's a subsequent
member of the struct.

Index: cod1.c
===================================================================
--- cod1.c    (revision 413)
+++ cod1.c    (working copy)
   -3453,6 +3453,7   
     // See if we can use register that parameter was passed in
     if (regcon.params && e->EV.sp.Vsym->Sclass == SCfastpar &&
     regcon.params & mask[e->EV.sp.Vsym->Spreg] &&
+    !(e->Eoper == OPvar && e->EV.sp.Voffset > 0) && // Must be at the base of
that variable
     sz <= REGSIZE)            // make sure no 'paint' to a larger size
happened
     {
     reg = e->EV.sp.Vsym->Spreg;

=========================
Reduced test case:
=========================
struct Snake {
    short a, b;
}

void venom(short dd)
{
  assert(dd == 'B');
}

void serpent( Snake ss ) {
  venom(ss.b);
}

void main(){
    Snake s;
    s.a = 'A';
    s.b = 'B';
    serpent( s );
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 12 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3914


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com


--- Comment #3 from Walter Bright <bugzilla digitalmars.com> 2010-03-12
21:59:21 PST ---
changeset 416

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 12 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3914


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #4 from Don <clugdbug yahoo.com.au> 2010-04-09 19:15:20 PDT ---
Fixed DMD1.058 and DMD2.042.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 09 2010