Mercury Bugs - mercury
View Issue Details
0000228mercuryBugpublic2011-11-10 02:502011-11-14 01:36
Reporterjuliensf 
Assigned Tojuliensf 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000228: library/lexer.c cannot be compiled with MSVC
DescriptionIn Rotd-2011-11-10 (and for a probably a few months before) we generate C code for
library/lexer.c in the hlc.gc grade that cannot be compiled with MSVC. (The 11.07 branch is fine.)
There are two issues:

lexer.c(171) : error C2133: 'mercury__lexer__lexer__field_locns_token_0_3' : unknown size
lexer.m(2466) : error C2440: 'type cast' : cannot convert from 'MR_Float' to 'MR_Float-Dword'
etc etc
Additional InformationFor issue 1 we just need to emit the array size in the forwarding declaration:

static const MR_DuArgLocn mercury__lexer__lexer__field_locns_token_0_3[];

(Does anyone know where it's generated?)

I haven't looked into the second issue yet.
TagsNo tags attached.
Attached Files

Notes
(0000395)
wangp   
2011-11-10 10:48   
Probably somewhere in rtti_out.m, where is_array appears.
(0000396)
juliensf   
2011-11-10 13:45   
I doubt that, given that rtti_out.m is used for LLDS backend. The problem appears to be in mlds_to_c's
handling of some RTTI defns. It hasn't shown up before because vector_common_data and the arrays
for alloc_sites are handled specially (i.e. they are written out in a form that is compatible with MSVC.) Arrays of MR_DuArgLocns are written out using the normal output code for declarations.
(0000397)
juliensf   
2011-11-10 15:45   
I've posted a diff that fixes the first problem.
(0000398)
juliensf   
2011-11-11 01:11   
The second problem is caused by the macro MR_float_word_bits, defined as follows

#define MR_float_word_bits(F, I) \
   ((union MR_float_Dword) (MR_Float) (F)).w[(I)])

MSVC does not appear to allow casts to unions, see
<http://msdn.microsoft.com/en-us/library/d9f2bsy2.aspx>
(0000399)
juliensf   
2011-11-11 01:56   
The code in library/lexer.c that causes the trouble is:
{
  MR_Word base;
  base = (MR_Word) MR_mkword(MR_mktag(3), MR_new_object(MR_Word, ((MR_Integer) 3 * i sizeof(MR_Word)), NULL, NULL));
  *mercury__lexer__Token_4 = base;
  MR_hl_field(MR_mktag(3), base, 0) = ((MR_Box) (MR_Word) ((MR_Integer) 1));
  MR_hl_field(MR_mktag(3), base, 1) = ((MR_Box) (MR_Word) (MR_float_word_bits(mercury__lexer__Float_5, (MR_Integer) 0)));
  MR_hl_field(MR_mktag(3), base, 2) = ((MR_Box) (MR_Word) (MR_float_word_bits(mercury__lexer__Float_5, (MR_Integer) 1)));
}

This can be made to work with MSVC by generating slightly different code that does the same thing, e.g.

{
 MR_Word base;
 union MR_Float_Dword foo;
 base = (MR_Word) MR_mkword(MR_mktag(3), MR_new_object(MR_Word, ((MR_Integer) 3 * sizeof(MR_Word)), NULL, NULL));
 *mercury__lexer__Token_4 = base;
 MR_hl_field(MR_mktag(3), base, 0) = ((MR_Box) (MR_Word) ((MR_Integer) 1));
 foo.f = mercury__lexer__Float_5;
 MR_hl_field(MR_mktag(3), base, 1) = ((MR_Box) (MR_Word) (foo.w[0]));
 MR_hl_field(MR_mktag(3), base, 2) = ((MR_Box) (MR_Word) (foo.w[1]));
}

(Manually making the above changes is sufficient to allow lexer.c to compile with MSVC.)
(0000400)
wangp   
2011-11-11 09:51   
It would be easier just to use an inline function, as for MR_float_from_dword.

The low-level C backend has special case handling to detect such pairs of assignments, and rewrites it as a single assignment statement. I can make the hlc backend do that as well.
(0000401)
juliensf   
2011-11-11 13:19   
Hi Peter,

Either fix is fine by me - if the fix you suggest is easier to implement then we should do that.
(0000402)
wangp   
2011-11-11 13:49   
Can you do the first part (the inline function)? I don't have a Windows development environment set up.

I will do the rewriting as a separate change. MR_float_word_bits will still remain for the possibility that the two instructions are separated or reordered.
(0000403)
juliensf   
2011-11-11 14:26   
Sure. Just so I'm clear, the intention is to add the inline function:

  MR_Word MR_float_word_bit(MR_Float, MR_Integer)

and then generate:

  MR_hl_field(MR_mktag(3), base, 1) = ((MR_Box) MR_float_word_bit(mercury__lexer__Float_5, 0);
  MR_hl_field(MR_mktag(3), base, 2) = ((MR_Box) MR_float_word_bit(mercury__lexer__Float_5, 1);

or do you have something else in mind?

----------

I don't see how MR_float_word_bits can remain in its current form -- any use of it will mean the
C code can't be compiled with MSVC.
(0000404)
wangp   
2011-11-11 14:56   
Yes. Will this not work?

    MR_EXTERN_INLINE MR_Float
    MR_float_word_bits(MR_Float f, MR_Integer i)
    {
        union MR_Float_Dword dw;
        dw.f = f;
        return dw.w[i];
    }
(0000405)
juliensf   
2011-11-11 16:26   
I will check later this evening -- while I do have a Windows development environment set up,
it's at home at the moment and I'm not. (The Windows machines at work have been requisitioned for
G12 benchmarking.)
(0000406)
juliensf   
2011-11-11 19:25   
That does the trick; I've retained the existing (macro) definition for MR_float_word_bits if the C compiler is
GCC or clang. I'll post a diff to mercury-reviews later this evening.

Issue History
2011-11-10 02:50juliensfNew Issue
2011-11-10 10:48wangpNote Added: 0000395
2011-11-10 13:45juliensfNote Added: 0000396
2011-11-10 15:45juliensfNote Added: 0000397
2011-11-11 01:11juliensfNote Added: 0000398
2011-11-11 01:56juliensfNote Added: 0000399
2011-11-11 01:56juliensfStatusnew => confirmed
2011-11-11 09:51wangpNote Added: 0000400
2011-11-11 13:19juliensfNote Added: 0000401
2011-11-11 13:49wangpNote Added: 0000402
2011-11-11 14:26juliensfNote Added: 0000403
2011-11-11 14:56wangpNote Added: 0000404
2011-11-11 16:26juliensfNote Added: 0000405
2011-11-11 19:25juliensfNote Added: 0000406
2011-11-14 01:36juliensfStatusconfirmed => resolved
2011-11-14 01:36juliensfResolutionopen => fixed
2011-11-14 01:36juliensfAssigned To => juliensf