stack overflow in strict function depending on return type
With -O
or up, but not with -fno-strictness
, the following program terminates with a stack overflow:
goInt :: Integer -> Integer -> Int
goInt 500 250000 = 0
goInt x 250000 = goInt (x+1) 1
goInt x y = goInt x (y+1)
main = do
print $ goInt 1 1
In contrast, the following program runs just fine even though the differences should not impact strictness:
import Debug.Trace
goInteger :: Integer -> Integer -> Integer
goInteger 500 250000 = 0
goInteger x 250000 = goInteger (x+1) 1
goInteger x y = goInteger x (y+1)
goIntTrace :: Integer -> Integer -> Int
goIntTrace 500 250000 = 0
goIntTrace x 250000 = goIntTrace (x+1) 1
goIntTrace x y = (if y < 0 then trace "" else id) goIntTrace x (y+1)
main = do
print $ goInteger 1 1
print $ goIntTrace 1 1
goInteger
does not overflow the stack even though it only differs in the type of the return value.
goIntTrace
does not overflow the stack even though goInt
is already strict in y
. Trying to make goInt
"stricter" via seq
s or bangs instead does not seem to have the same effect without the threat of IO.
The behavior could be reproduced on at least ghc 7.0.1 and 7.4.1, linux x86_64.
Trac metadata
Trac field | Value |
---|---|
Version | 7.4.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |