On 11 May 2010 23:03, Daniel Gibson <metalcae...@gmail.com> wrote:

> Package: gdc-4.3
> Version: 1:1.046-4.3.4-5
> Severity: serious
>
>
> The MD5-sums calculated by std.md5 are seriously broken - they're not
> only wrong, they're different on each run..
> gdc-4.1 and the closed-source dmd do *not* have this bug. Because
> md5.d in the gdc-4.1 and gdc-4.3 package sources are identical I file
> this as a bug in the compiler, not libphobos.
> I consider this a serious bug because it makes std.md5 unusable and
> probably affects other code as well (why should it only break the MD5
> code).
>
> I attached a simple testcase to demonstrate this bug. When it's build
> with gdc-4.1 I get the following output:
> "900150983CD24FB0D6963F7D28E17F72", when it's built with gdc-4.3 I
> get:
> "9BB8D85B9EC69BAAE48AFD6DC642C4B7
> Error: AssertError Failure md5test.d(8)"
> or "73295B9A9D13003D9E6065260759FBD4
> Error: AssertError Failure md5test.d(8)"
> ... (a different sum on each run).
>
> Cheers,
> - Daniel
>
>
>
Thank-you for your report, this seems to be a problem with gdc's inline asm.

Attached is the minimal code to reproduce, however, it seems that I can get
it in even less.

asm
{
   naked ;
   mov EAX x ;
   ret ;
}

Haven't looked into it properly yet, but conjures the thought of data not
being initialised properly.


First advancements though, turning off asm in std.md5 seems like a likely
quick-fix for the time being. Just comparing, GCC can produce the rol opcode
from shifts. Actually, produces _exactly_ the same code as the inline
assembly in the D file (with the exception of a different call frame setup).
So is not likely we are loosing any optimisation either way.

I'd hate to think where else in phobos is affected by this...


Regards

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
import std.stdio;

uint test_asm(uint x, uint n)
{
    asm
    {
	naked ;
/+	mov ECX, n ; +/
	mov EAX, x ;
/+	rol EAX, CL ; +/
	ret ;	/+ Returns 42 in gdc-4.1.
	    	A Random number is returned in gdc-4.3 +/
    }
}

void main()
{
    writefln( test_asm(42, 1) );
}

Reply via email to