Mercury Bugs - mercury
View Issue Details
0000382mercuryBugpublic2015-03-15 00:222015-03-16 03:15
Reporterpbone 
Assigned Tozs 
PrioritynormalSeveritycrashReproducibilityalways
StatusresolvedResolutionfixed 
Platformx86_64OSDebianOS Version8.0
Product Version 
Target VersionFixed in Version 
Summary0000382: arg-pack-bits optimisation broken with foreign_enums.
Description
The arg-pack-bits optimisation is incorrectly applied to members of structures which are foreign enums. In this example I have two types each has two fields and therefore could be stored in 1 bit each. However they are foreign enums and in this case may contain values that may use an arbitrary number of bits. Mercury incorrectly assumes that they use fewer bits and attempts to pack them.
Steps To Reproduce
Code that uses the following structure is mis-compiled. I'm attaching a full example. Note that the 3rd field is necessary to trigger the crash.

:- type addrinfo
    ---> addrinfo(
                ai_family :: family,
                ai_socktype :: socktype,
                ai_protocol :: protocol_num
            ).

:- type family
    ---> fam_inet
    ; fam_inet6.

:- type socktype
    ---> sock_stream
    ; sock_dgram.

:- pragma foreign_enum("C", family/0,
    [fam_inet - "AF_INET",
     fam_inet6 - "AF_INET6"]).

:- pragma foreign_enum("C", socktype/0,
    [sock_stream - "SOCK_STREAM",
     sock_dgram - "SOCK_DGRAM"]).

The error goes away when I set --arg-pack-bits=0
Additional InformationNote that the solution will need to be aware of cases where the foreign enum is in the implementation section of a different module.
TagsNo tags attached.
Attached Files? bug_pack_bits.m (2,542) 2015-03-15 00:22
https://bugs.mercurylang.org/file_download.php?file_id=239&type=bug

Notes
(0000817)
zs   
2015-03-15 04:31   
I know what is causing the problem. The code in du_type_layout.m that decides on whether
and how the arguments in a memory cell will be packed is invoked at the end of pass 2
in the making of the HLDS, but the foreign_enum pragma is processed only in pass 3.
This means that while du_type_layout.m does the right thing, it is given wrong data.
Since it thinks that family and socktype are Mercury enums that are NOT exported to
other languages, it believes it is safe to compress them in fields.

I am working on a change to move the processing of those pragmas to pass 2.
Getting rid of the pass system would be even better, but that would conflict with
my work on the item list structure.
(0000818)
pbone   
2015-03-15 10:06   
Thanks Zoltan.

Just a quick note regarding "Mercury enums that are NOT exported to
other languages," These enums aren't exported from Mercury, they're imported to Mercury.

Cheers.
(0000819)
zs   
2015-03-16 03:15   
Fixed in commit 6dd74cad6471b9c1db11575034d7a866c8429a87, 2015 march 16.

Issue History
2015-03-15 00:22pboneNew Issue
2015-03-15 00:22pboneFile Added: bug_pack_bits.m
2015-03-15 01:10zsAssigned To => zs
2015-03-15 01:10zsStatusnew => assigned
2015-03-15 04:31zsNote Added: 0000817
2015-03-15 10:06pboneNote Added: 0000818
2015-03-16 03:15zsNote Added: 0000819
2015-03-16 03:15zsStatusassigned => resolved
2015-03-16 03:15zsResolutionopen => fixed