#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