Bug 4323 – std.demangle incorrectly handles template floating point numbers

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
druntime
Product
D
Version
D1 (retired)
Platform
Other
OS
Mac OS X
Creation time
2010-06-15T11:38:00Z
Last change time
2014-06-06T22:34:28Z
Keywords
patch, wrong-code
Assigned to
nobody
Creator
doob

Comments

Comment #0 by doob — 2010-06-15T11:38:04Z
According to the ABI spec the mangled form of template floating point numbers looks like this: Value: e HexFloat HexFloat: N HexDigits P Exponent HexDigits P Exponent But std.demnalge doesn't seem to handle the exponent, it doesn't handle the 'P'. The unittests that test this are also incorrect. The first one looks like this: mangled form: _D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf demangled form: float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial As far as I can see the mangled form doesn't follow the spec or what dmd produces. module test; float factorial (T...) () { return float.init; } void main () { factorial!(4.2, "hello", null); } Compiling the above code and running the "nm" command on the resulting binary shows that "factorial" with the above given values is mangled as: _D4test57__T9factorialVde8666666666666667PN1VAyaa5_68656c6c6fVPvnZ9factorialFZf After all the 6s the is a 7 and then a P. In the std.demangle unittest the P is missing, also at the end of the mangled name is a Z which is missing in the unittest.
Comment #1 by kennytm — 2011-05-08T02:14:35Z
With core.demangle it now resolves _D4test57__T9factorialVde8666666666666667PN1VAyaa5_68656c6c6fVPvnZ9factorialFZf into: float test.factorial!(8.400000, "hello", null).factorial() The only problem is the floating point number is 2 times bigger than the expected.
Comment #2 by kennytm — 2011-05-08T02:45:28Z
The demangler forgot to put the 'p', making the exponent part totally ignored. Also, using the '%f' format makes floating point number that is extremely small becomes 0.00000. I think '%g' is more suitable. diff --git a/src/core/demangle.d b/src/core/demangle.d index 6d37633..b2ab00d 100644 --- a/src/core/demangle.d +++ b/src/core/demangle.d @@ -368,6 +368,7 @@ private struct Demangle next(); } match( 'P' ); + tbuf[tlen++] = 'p'; if( 'N' == tok() ) { tbuf[tlen++] = '-'; @@ -386,7 +387,7 @@ private struct Demangle tbuf[tlen] = 0; debug(info) printf( "got (%s)\n", tbuf.ptr ); val = strtold( tbuf.ptr, null ); - tlen = snprintf( tbuf.ptr, tbuf.length, "%Lf", val ); + tlen = snprintf( tbuf.ptr, tbuf.length, "%Lg", val ); debug(info) printf( "converted (%.*s)\n", cast(int) tlen, tbuf.ptr ); put( tbuf[0 .. tlen] ); }
Comment #3 by kennytm — 2011-05-08T09:47:59Z
Comment #4 by kennytm — 2011-06-19T11:41:14Z
Comment #5 by jcrapuchettes — 2014-06-06T22:34:28Z
Since D1 is no longer in development, I'm closing this issue.