2024-03-29 03:26 AEDT

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

-Relationships
+Relationships

-Notes

~0000395

wangp (developer)

Probably somewhere in rtti_out.m, where is_array appears.

~0000396

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.

~0000397

juliensf (administrator)

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

~0000398

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
<http://msdn.microsoft.com/en-us/library/d9f2bsy2.aspx>

~0000399

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

~0000400

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.

~0000401

juliensf (administrator)

Hi Peter,

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

~0000402

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.

~0000403

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.

~0000404

wangp (developer)

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

~0000406

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.
+Notes

-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