From a3b8d26c1ffdb405205bd7d937b201f57641770c Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Fri, 20 Jan 2017 18:06:14 +0300 Subject: [PATCH] runtime: Avoid UB in shift operations --- runtime/src/main/cpp/Operator.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/runtime/src/main/cpp/Operator.cpp b/runtime/src/main/cpp/Operator.cpp index 6d751e06f09..e88bbeb3bba 100644 --- a/runtime/src/main/cpp/Operator.cpp +++ b/runtime/src/main/cpp/Operator.cpp @@ -218,10 +218,13 @@ KInt Kotlin_Int_or_Int (KInt a, KInt b) { return a | b; } KInt Kotlin_Int_xor_Int (KInt a, KInt b) { return a ^ b; } KInt Kotlin_Int_and_Int (KInt a, KInt b) { return a & b; } KInt Kotlin_Int_inv (KInt a ) { return ~a; } -KInt Kotlin_Int_shl_Int (KInt a, KInt b) { return a << b; } -KInt Kotlin_Int_shr_Int (KInt a, KInt b) { return a >> b; } + +// According to C++11 the result is undefined if the second operator is < 0 or >= . +// We avoid it by using only the least significant bits +KInt Kotlin_Int_shl_Int (KInt a, KInt b) { return a << (b & 31); } +KInt Kotlin_Int_shr_Int (KInt a, KInt b) { return a >> (b & 31); } KInt Kotlin_Int_ushr_Int (KInt a, KInt b) { - return static_cast(a) >> b; + return static_cast(a) >> (b & 31); } KByte Kotlin_Int_toByte (KInt a ) { return a; } @@ -285,10 +288,13 @@ KLong Kotlin_Long_xor_Long (KLong a, KLong b) { return a ^ b; } KLong Kotlin_Long_or_Long (KLong a, KLong b) { return a | b; } KLong Kotlin_Long_and_Long (KLong a, KLong b) { return a & b; } KLong Kotlin_Long_inv (KLong a ) { return ~a; } -KLong Kotlin_Long_shl_Int (KLong a, KInt b) { return a << b; } -KLong Kotlin_Long_shr_Int (KLong a, KInt b) { return a >> b; } + +// According to C++11 the result is undefined if the second operator is < 0 or >= . +// We avoid it by using only the least significant bits +KLong Kotlin_Long_shl_Int (KLong a, KInt b) { return a << (b & 63); } +KLong Kotlin_Long_shr_Int (KLong a, KInt b) { return a >> (b & 63); } KLong Kotlin_Long_ushr_Int (KLong a, KInt b) { - return static_cast(a) >> b; + return static_cast(a) >> (b & 63); } KByte Kotlin_Long_toByte (KLong a ) { return a; }