#1844: Unexpected behavior with INLINE pragma
------------------------+---------------------------------------------------
    Reporter:  calvins  |       Owner:          
        Type:  bug      |      Status:  new     
    Priority:  normal   |   Component:  Compiler
     Version:  6.8.1    |    Severity:  normal  
    Keywords:  INLINE   |    Testcase:          
Architecture:  x86      |          Os:  Linux   
------------------------+---------------------------------------------------
 I have not been able to create a small isolated test case that illustrates
 the problem because there are too many dependencies on other code, but I
 will upload a small tarball that illustrates the problem.

 I have the following code:

 {{{
 {-# INLINE triple #-}
 triple :: Subject -> Predicate -> Object -> Triple
 triple subj pred obj
   | isLNode subj     =  error $ "subject must be UNode or BNode: " ++ show
 subj
   | isBNode pred     =  error $ "predicate must be UNode, not BNode: " ++
 show pred ++ debug pred -- 1
   | isLNode pred     =  error $ "predicate must be UNode, not LNode: " ++
 show pred    -- 2
   | otherwise        =  Triple subj pred obj
   where debug (UNode _)    = " [UNode]"
         debug (BNode _)    = " [BNode]"
         debug (BNodeGen _) = " [BNodeGen]"
         debug (LNode _)    = " [LNode]"

 {-# INLINE isBNode #-}
 isBNode :: Node -> Bool
 isBNode (BNode _)    = True
 isBNode (BNodeGen _) = True
 isBNode _            = False

 {-# INLINE isLNode #-}
 isLNode :: Node -> Bool
 isLNode (LNode _) = True
 isLNode _         = False

 data Node =
   UNode {-# UNPACK #-} !FastString
   | BNode {-# UNPACK #-} !FastString
   | BNodeGen  {-# UNPACK #-} !Int
   | LNode {-# UNPACK #-} !LValue
 }}}

 When this along with all the other supporting code is compiled with -O2,
 then on a particular test file, the error branch labeled 1 in the
 ''triple'' function above is entered, even though the guard test should
 have evaluated to false. The error message calls the debug function which
 shows that the type of node was a UNode, but as you can see, isBNode
 should always evaluate to false unless the node is a BNode or BNodeGen.

 The exact error message is:


 {{{
 ttlparse: predicate must be UNode, not BNode: <(0,
 http://www.w3.org/2001/sw/DataAccess/df1/tests/test-00.ttl#x)> [UNode]
 }}}


 If I change the INLINE pragma to NOINLINE, the problem disappears, and the
 code takes the otherwise branch as it is supposed to.

 Now the really bizarre behavior: if I switch the two guard lines 1 and 2
 in the above code, then it runs fine with no error, '''even with the
 INLINE pragma'''.

 The data is the same in both cases, and the ''triple'' function is the
 same apart from the order of the second guard and the third guard.

 As I stated, using NOINLINE, it doesn't matter which of the guards labeled
 1 and 2 is first, but with the INLINE pragma, there is an error if the
 order is 1 2 but no error if the order is 2 1.

 To see the problem, save the tarball and do the following:

 {{{
 tar xzf rdf4h.tar.gz
 chmod u+x debug.sh
 ./debug.sh
 }}}

 The ''debug.sh'' script builds the project and runs the test, which will
 error out with the message I included above.

 If you then edit RDF.hs and switch lines 138 and 139 (labeled as 1 and 2
 in the code above), you should then see a different message that is the
 result of successfully parsing the file.

 Please let me know if you have any questions or I can help in any way.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1844>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to