diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2019-05-24 11:23:01 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-06-01 11:18:57 -0400 |
commit | 1503da32d26fb59fb6ebb620bfd0f8c08638f627 (patch) | |
tree | 8933e408efdbdec39de3e547b153aa1522c5714f /testsuite/tests/codeGen | |
parent | 76e5889017ee4ac688901d37f2fa684e807769b6 (diff) | |
download | haskell-1503da32d26fb59fb6ebb620bfd0f8c08638f627.tar.gz |
Fix rewriting invalid shifts to errors
Fixes #16449.
5341edf3 removed a code in rewrite rules for bit shifts, which broke the
"silly shift guard", causing generating invalid bit shifts or heap
overflow in compile time while trying to evaluate those invalid bit
shifts.
The "guard" is explained in Note [Guarding against silly shifts] in
PrelRules.hs.
More specifically, this was the breaking change:
--- a/compiler/prelude/PrelRules.hs
+++ b/compiler/prelude/PrelRules.hs
@@ -474,12 +474,11 @@ shiftRule shift_op
; case e1 of
_ | shift_len == 0
-> return e1
- | shift_len < 0 || wordSizeInBits dflags < shift_len
- -> return (mkRuntimeErrorApp rUNTIME_ERROR_ID wordPrimTy
- ("Bad shift length" ++ show shift_len))
This patch reverts this change.
Two new tests added:
- T16449_1: The original reproducer in #16449. This was previously
casing a heap overflow in compile time when CmmOpt tries to evaluate
the large (invalid) bit shift in compile time, using `Integer` as the
result type. Now it builds as expected. We now generate an error for
the shift as expected.
- T16449_2: Tests code generator for large (invalid) bit shifts.
Diffstat (limited to 'testsuite/tests/codeGen')
-rw-r--r-- | testsuite/tests/codeGen/should_compile/T16449_1.hs | 8 | ||||
-rw-r--r-- | testsuite/tests/codeGen/should_compile/all.T | 2 | ||||
-rw-r--r-- | testsuite/tests/codeGen/should_run/T16449_2.hs | 9 | ||||
-rw-r--r-- | testsuite/tests/codeGen/should_run/T16449_2.stderr | 1 | ||||
-rw-r--r-- | testsuite/tests/codeGen/should_run/all.T | 1 |
5 files changed, 21 insertions, 0 deletions
diff --git a/testsuite/tests/codeGen/should_compile/T16449_1.hs b/testsuite/tests/codeGen/should_compile/T16449_1.hs new file mode 100644 index 0000000000..b1ec71efef --- /dev/null +++ b/testsuite/tests/codeGen/should_compile/T16449_1.hs @@ -0,0 +1,8 @@ +module T16449_1 where + +import Data.Bits (setBit) + +f :: Int +f = foldl setter 0 $ zip [0..] [()] + where + setter v (ix, _) = setBit v ix diff --git a/testsuite/tests/codeGen/should_compile/all.T b/testsuite/tests/codeGen/should_compile/all.T index 547814a0d6..ed7f5f3699 100644 --- a/testsuite/tests/codeGen/should_compile/all.T +++ b/testsuite/tests/codeGen/should_compile/all.T @@ -59,3 +59,5 @@ test('T15155', test('T15155l', when(unregisterised(), skip), makefile_test, []) + +test('T16449_1', normal, compile, ['']) diff --git a/testsuite/tests/codeGen/should_run/T16449_2.hs b/testsuite/tests/codeGen/should_run/T16449_2.hs new file mode 100644 index 0000000000..3424d43e25 --- /dev/null +++ b/testsuite/tests/codeGen/should_run/T16449_2.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Prim +import GHC.Int + +-- Shift should be larger than the word size (e.g. 64 on 64-bit) for this test. +main = print (I# (uncheckedIShiftL# 1# 1000#)) diff --git a/testsuite/tests/codeGen/should_run/T16449_2.stderr b/testsuite/tests/codeGen/should_run/T16449_2.stderr new file mode 100644 index 0000000000..869a5b0f91 --- /dev/null +++ b/testsuite/tests/codeGen/should_run/T16449_2.stderr @@ -0,0 +1 @@ +T16449_2: Bad shift length 1000 diff --git a/testsuite/tests/codeGen/should_run/all.T b/testsuite/tests/codeGen/should_run/all.T index 6b4d772627..f43ced136c 100644 --- a/testsuite/tests/codeGen/should_run/all.T +++ b/testsuite/tests/codeGen/should_run/all.T @@ -195,3 +195,4 @@ test('T15892', extra_run_opts('+RTS -G1 -A32k -RTS') ], compile_and_run, ['-O']) test('T16617', normal, compile_and_run, ['']) +test('T16449_2', exit_code(1), compile_and_run, ['']) |