[dmd-internals] building dmd with the microsoft compiler

Rainer Schuetze r.sagitario at gmx.de
Sun Nov 13 08:42:55 PST 2011


When compiling dmd with the Microsoft compiler, I gag thousands of 
warnings (at highest warning level 4) with:

#pragma warning(disable:4996) // This function or variable may be unsafe.
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4101) // unreferenced local variable
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4146) // unary minus operator applied to 
unsigned type, result still unsigned
#pragma warning(disable:4244) // conversion from 'int' to 'unsigned 
short', possible loss of data
#pragma warning(disable:4245) // conversion from 'int' to 'unsigned 
int', signed/unsigned mismatch
#pragma warning(disable:4018) // signed/unsigned mismatch
#pragma warning(disable:4389) // signed/unsigned mismatch
#pragma warning(disable:4505) // unreferenced local function has been 
removed
#pragma warning(disable:4701) // potentially uninitialized local 
variable 'm' used
#pragma warning(disable:4201) // nonstandard extension used : nameless 
struct/union
#pragma warning(disable:4189) // local variable is initialized but not 
referenced
#pragma warning(disable:4102) // unreferenced label
#pragma warning(disable:4800) // forcing value to bool 'true' or 'false' 
(performance warning)

Still, more than a hundred warnings remain, the more interesting ones 
(line numbers might be off a little because of my changes):

- I did not figure out what's wrong with this, but it sounds dangerous:
         RTLSYMS
.\backend\rtlsym.c(95) : warning C4806: '|' : unsafe operation: no value 
of type 'bool' promoted to type 'int' can equal the given constant
.\backend\rtlsym.c(95) : warning C4554: '|' : check operator precedence 
for possible error; use parentheses to clarify precedence

- probably false positives regarding calculations with bools like:
         i ^= d1 > d2;
.\backend\evalu8.c(1667) : warning C4805: '^=' : unsafe mix of type 
'int' and type 'bool' in operation
     return (x - sign) ^ -sign;
.\intrange.c(24) : warning C4804: '-' : unsafe use of type 'bool' in 
operation

- lots of "truncation of constant value", which are more unsigned -> 
signed conversion
     static char nops[7] = { 0x90,0x90,0x90,0x90,0x90,0x90,0x90 };
.\backend\cod3.c(324) : warning C4309: 'initializing' : truncation of 
constant value

- but this seems problematic, because the array value is later used as 
an index assumed positive
         static char invconvtab[] = { .... OPd_ld, ... };
.\backend\cgelem.c(377) : warning C4305: 'initializing' : truncation 
from 'OPER' to 'char'
.\backend\cgelem.c(377) : warning C4309: 'initializing' : truncation of 
constant value

- too large shift count:
         value |= value << 32;
.\backend\cod2.c(3312) : warning C4293: '<<' : shift count negative or 
too big, undefined behavior

- the following looks actually like a bug:
     if (!config.flags4 & CFG4optimized)
.\backend\cgreg.c(53) : warning C4806: '&' : unsafe operation: no value 
of type 'bool' promoted to type 'int' can equal the given constant

- this is probably another bug:
             if (sc->func && !((TypeFunction *)t1)->trust <= TRUSTsystem)
.\expression.c(7680) : warning C4804: '<=' : unsafe use of type 'bool' 
in operation

- switch on enumerators with values not part of the enumeration:
.\iasm.c(4053) : warning C4063: case '237' is not a valid value for 
switch of enum 'TOK'

- lots of warnings regarding unreachable code, mostly due to 
preprocessor conditionals

Rainer


On 13.11.2011 17:13, Rainer Schuetze wrote:
> Hi,
>
> a few days ago, I was trying to figure out why dmd takes so long 
> compiling my projects. (The usual development build time for 
> VisualD+parser is about 40 seconds which starts to get annoying. With 
> enabled GC it was more than a minute. Comparing this with the C++ 
> project at work which is about 50 times larger, but only takes about 
> 10 seconds to (incrementally) build with changes to a few files, I 
> think there is something wrong with the D compilation model. But this 
> is a different topic.)
>
> Activating the profiler didn't help (crashes or takes forever), so I 
> pushed the dmd source through the Microsoft compiler (I'm currently 
> using cl v15 that comes with VS2008). Using the Microsoft compiler has 
> several advantages
>
> - way better debug information and integration into current debuggers
> - better support for instrumented/sampling profiling tools
> - better dependency handling for building dmd (if used from within 
> Visual Studio)
> - the executable can use up to 4GB memory on Win 64-bit host, up to 
> 3GB memory on Win32
>
> The downsides are
>
> - no 80-bit float support
> - no C99 sprintf (%j, %z, %a)
> - restricted structured exception handling
>
> I have patched the compiler to use handcrafted implementations and it 
> now passes the dmd test suite.
>
> Quite a bit to my surprise, the compiler is also almost twice as fast 
> on my projects as the dmc compiled dmd! The test suite runs a bit 
> slower though (5% to 10%).
>
> Is there interest in adding the patches to the dmd source? I would 
> like to do some cleanup before creating a pull request.
>
> The major changes are with respect to the 80-bit floats, because this 
> also leaks into the backend. Mostly, it's replacing "long double" with 
> my implementation "long_double". I've seen "d-gcc-real.h" being used 
> if IN_GCC  is defined, but the defined type real_t is only referred to 
> partially. I wonder whether this is still in use (by LDC/GDC?) and 
> whether it ever passed the test suites?
>
> The C99 printf functions are overloaded by inserting an include file 
> on the command line, I would prefer if these would go into port.c/h, 
> but these would need to be included by the backend aswell then.
>
> I have also built a 64-bit executable of dmd building 32-bit code, but 
> it does not perform aswell (somewhere between dmc and msc 32-bit 
> versions).
>
> Rainer
>
>



More information about the dmd-internals mailing list