summaryrefslogtreecommitdiff
path: root/compiler/stranal
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2014-06-11 19:53:06 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2014-06-11 20:56:38 +0100
commit7d9feb264a4fc3c15d1e5f88f2e7a04202ed9743 (patch)
tree5005a67f94c508094c0aeb7779fc8a015d96b913 /compiler/stranal
parentc8295c0bd58485db5572d3c35427d321bdf1b7d0 (diff)
downloadhaskell-7d9feb264a4fc3c15d1e5f88f2e7a04202ed9743.tar.gz
Fix a serious, but rare, strictness analyser bug (Trac #9128)
In a special case for trivial RHSs (see DmdAnal.unpackTrivial), I'd forgotten to include a demand for the RHS itself. See Note [Remember to demand the function itself]. Thanks to David Terei for guiding me to the bug, at PLDI in Edinburgh.
Diffstat (limited to 'compiler/stranal')
-rw-r--r--compiler/stranal/DmdAnal.lhs11
1 files changed, 10 insertions, 1 deletions
diff --git a/compiler/stranal/DmdAnal.lhs b/compiler/stranal/DmdAnal.lhs
index bd7b5c33bf..f240be4cd7 100644
--- a/compiler/stranal/DmdAnal.lhs
+++ b/compiler/stranal/DmdAnal.lhs
@@ -596,7 +596,16 @@ dmdAnalRhs :: TopLevelFlag
dmdAnalRhs top_lvl rec_flag env id rhs
| Just fn <- unpackTrivial rhs -- See Note [Demand analysis for trivial right-hand sides]
, let fn_str = getStrictness env fn
- = (fn_str, emptyDmdEnv, set_idStrictness env id fn_str, rhs)
+ fn_fv | isLocalId fn = unitVarEnv fn topDmd
+ | otherwise = emptyDmdEnv
+ -- Note [Remember to demand the function itself]
+ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ -- fn_fv: don't forget to produce a demand for fn itself
+ -- Lacking this caused Trac #9128
+ -- The demand is very conservative (topDmd), but that doesn't
+ -- matter; trivial bindings are usually inlined, so it only
+ -- kicks in for top-level bindings and NOINLINE bindings
+ = (fn_str, fn_fv, set_idStrictness env id fn_str, rhs)
| otherwise
= (sig_ty, lazy_fv, id', mkLams bndrs' body')