2024-06-26 09:00 AEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000228mercuryBugpublic2011-11-14 01:36
Assigned Tojuliensf 
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




wangp (developer)

Probably somewhere in rtti_out.m, where is_array appears.


juliensf (administrator)

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.


juliensf (administrator)

I've posted a diff that fixes the first problem.


juliensf (administrator)

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


juliensf (administrator)

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.)


wangp (developer)

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.


juliensf (administrator)

Hi Peter,

Either fix is fine by me - if the fix you suggest is easier to implement then we should do that.


wangp (developer)

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.


juliensf (administrator)

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.


wangp (developer)

Yes. Will this not work?

    MR_float_word_bits(MR_Float f, MR_Integer i)
        union MR_Float_Dword dw;
        dw.f = f;
        return dw.w[i];


juliensf (administrator)

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.)


juliensf (administrator)

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
Date Modified Username Field Change
2011-11-10 02:50 juliensf New Issue
2011-11-10 10:48 wangp Note Added: 0000395
2011-11-10 13:45 juliensf Note Added: 0000396
2011-11-10 15:45 juliensf Note Added: 0000397
2011-11-11 01:11 juliensf Note Added: 0000398
2011-11-11 01:56 juliensf Note Added: 0000399
2011-11-11 01:56 juliensf Status new => confirmed
2011-11-11 09:51 wangp Note Added: 0000400
2011-11-11 13:19 juliensf Note Added: 0000401
2011-11-11 13:49 wangp Note Added: 0000402
2011-11-11 14:26 juliensf Note Added: 0000403
2011-11-11 14:56 wangp Note Added: 0000404
2011-11-11 16:26 juliensf Note Added: 0000405
2011-11-11 19:25 juliensf Note Added: 0000406
2011-11-14 01:36 juliensf Status confirmed => resolved
2011-11-14 01:36 juliensf Resolution open => fixed
2011-11-14 01:36 juliensf Assigned To => juliensf
+Issue History