diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2019-09-06 16:33:19 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-09-11 19:40:06 -0400 |
commit | c76cc0c6fa973ae8e083db5aeb4d19f37a64bb21 (patch) | |
tree | dab37f38d556f4d7b0c518675978adc8d15c745e /compiler/ghci | |
parent | 7ef6fe8f70156581ce8e370a90975fb96f98783a (diff) | |
download | haskell-c76cc0c6fa973ae8e083db5aeb4d19f37a64bb21.tar.gz |
Refactor bad coercion checking in a few places
We do bad coercion checking in a few places in the compiler, but they
all checked it differently:
- CoreToStg.coreToStgArgs:
Disallowed lifted-to-unlifted, disallowed changing prim reps even when
the sizes are the same.
- StgCmmExpr.cgCase:
Checked primRepSlot equality. This disallowed Int to Int64 coercions
on 64-bit systems (and Int to Int32 on 32-bit) even though those are
fine.
- CoreLint:
Only place where we do this right. Full rules are explained in Note
[Bad unsafe coercion].
This patch implements the check explained in Note [Bad unsafe coercion]
in CoreLint and uses it in CoreToStg.coreToStgArgs and
StgCmmExpr.cgCase.
This fixes #16952 and unblocks !1381 (which fixes #16893).
This is the most conservative and correct change I came up with that
fixes #16952.
One remaining problem with coercion checking is that it's currently done
in seemingly random places. What's special about CoreToStg.coreToStgArgs
and StgCmmExpr.cgCase? My guess is that adding assertions to those
places caught bugs before so we left assertions in those places. I think
we should remove these assertions and do coercion checking in CoreLint
and StgLint only (#17041).
Diffstat (limited to 'compiler/ghci')
-rw-r--r-- | compiler/ghci/ByteCodeGen.hs | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/compiler/ghci/ByteCodeGen.hs b/compiler/ghci/ByteCodeGen.hs index 2865aaeaa6..2ad089903b 100644 --- a/compiler/ghci/ByteCodeGen.hs +++ b/compiler/ghci/ByteCodeGen.hs @@ -1219,7 +1219,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l push_args = concatOL pushs_arg !d_after_args = d0 + wordsToBytes dflags a_reps_sizeW a_reps_pushed_RAW - | null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidRep + | null a_reps_pushed_r_to_l || not (isVoidRep (head a_reps_pushed_r_to_l)) = panic "ByteCodeGen.generateCCall: missing or invalid World token?" | otherwise = reverse (tail a_reps_pushed_r_to_l) @@ -1904,7 +1904,8 @@ atomPrimRep (AnnLit l) = typePrimRep1 (literalType l) -- #12128: -- A case expression can be an atom because empty cases evaluate to bottom. -- See Note [Empty case alternatives] in coreSyn/CoreSyn.hs -atomPrimRep (AnnCase _ _ ty _) = ASSERT(typePrimRep ty == [LiftedRep]) LiftedRep +atomPrimRep (AnnCase _ _ ty _) = + ASSERT(case typePrimRep ty of [LiftedRep] -> True; _ -> False) LiftedRep atomPrimRep (AnnCoercion {}) = VoidRep atomPrimRep other = pprPanic "atomPrimRep" (ppr (deAnnotate' other)) |