Ticket #5812 (closed bug: wontfix)

Opened 4 months ago

Last modified 4 months ago

Nasty interaction between MagicHash and CPP LANGUAGE pragmas

Reported by: erikd Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.2.2
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Incorrect result at runtime Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

Found this problem when trying to use MagicHash? and CPP in the same source file.

Small test program:

{-# LANGUAGE OverloadedStrings, MagicHash, BangPatterns  #-}
{-# LANGUAGE CPP #-}

import Data.ByteString (ByteString)
import Data.Int (Int64)

import qualified Data.ByteString.Char8 as B
import qualified Data.Char as C
import qualified Test.QuickCheck as QC

import GHC.Prim
import GHC.Types

readInt64 :: ByteString -> Int64
readInt64 bs =
        B.foldl' (\i c -> i * 10 + fromIntegral (mhDigitToInt c)) 0
             $ B.takeWhile C.isDigit bs

data Table = Table !Addr#

mhDigitToInt :: Char -> Int
mhDigitToInt (C# i) = I# (word2Int# $ indexWord8OffAddr# addr (ord# i))
  where
    !(Table addr) = table
    table :: Table
    table = Table
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
        \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#


-- A QuickCheck property. Test that for a number >= 0, converting it to
-- a string using show and then reading the value back with the function
-- under test returns the original value.
-- The functions under test only work on Natural numbers (the Conent-Length
-- field in a HTTP header is always >= 0) so we check the absolute value of
-- the value that QuickCheck generates for us.
prop_read_show_idempotent :: Integral a => (ByteString -> a) -> a -> Bool
prop_read_show_idempotent freader x =
    let px = abs x
    in px == freader (B.pack $ show px)

main :: IO ()
main =
    QC.quickCheck (prop_read_show_idempotent readInt64)

Compile and running that as:

ghc -Wall test.hs -o test && ./test
}}

generates an executable (with out any warnings) and when I run the executable it fails the QuickCheck test.

However, if I remove the LANGUAGE CPP pragma and recompile it, the program passes the QuickCheck test.

Using the two pragmas together makes correct code generate incorrect results.

Would like to see an error message if MagicHash and CPP are used in the same source file.

Change History

Changed 4 months ago by simonmar

  • status changed from new to infoneeded
  • difficulty set to Unknown

Perhaps you're running into the known issue with CPP and string gaps? http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#cpp-string-gaps

What makes you think the issue has something to do with MagicHash?

Changed 4 months ago by erikd

  • status changed from infoneeded to new

Yes, that's it. If I put the string on a single line it works.

Unfortunately, the suggested solution, adding trailing whitespace, isn't very convenient as my text editor is configured to remove all trailing whitespace on file save (a feature I really like).

Changed 4 months ago by simonmar

  • status changed from new to closed
  • resolution set to wontfix

Then my suggestion is to use ++ instead of string gaps. GHC will optimise it away anyway.

Note: See TracTickets for help on using tickets.