;;;; Signedness, which nothing in the corpus was exercising. ;;;; ;;;; Found by mutation testing: emit.ml chooses ashr vs lshr and slt vs ult ;;;; from the operand's type, and both choices could be hardcoded to one arm ;;;; with the whole suite still green — because no program shifted a negative ;;;; integer right, and none compared an unsigned value above 2^31. (defn main [] i32 ;; An arithmetic shift keeps the sign. A logical one on -8 gives a number ;; near 2^63, which is the wrong answer that looks like a huge right one. (print-i64 (>> (i64 -8) 1)) (newline) ; -4 (print-i64 (>> (i64 -1) 40)) (newline) ; -1, still, however far it goes ;; And unsigned stays unsigned: 3000000000 has its top bit set, so a signed ;; compare reads it as negative and answers the other way on every operator. (let [big (bit-or (<< (u32 1) 31) (u32 1000))] ; 2^31 + 1000 (print-line (if (< big (u32 5)) "wrong: signed compare" "big is not small")) (print-line (if (> big (u32 5)) "big is large" "wrong: signed compare")) ;; The same value through >>, which is logical on an unsigned type: a ;; signed shift here would keep the top bit and answer near 2^31 again. (print-i64 (i64 (>> big 31))) (newline)) ; 1 0)