diff --git a/CHANGES b/CHANGES index 88e15d91f8..814d5ff95f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +5.1.0-dev.301 | 2022-07-29 12:10:20 -0700 + + * Add btest for vector bit-shift operators (Tim Wojtulewicz, Corelight) + + * Handle error cases for bit-shift operators more cleanly (Tim Wojtulewicz, Corelight) + 5.1.0-dev.298 | 2022-07-29 12:00:57 -0700 * Update 3rdparty submodule to get patricia reformat (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 06087fc891..3a0f3b807a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.1.0-dev.298 +5.1.0-dev.301 diff --git a/src/Expr.cc b/src/Expr.cc index 7ba9559509..3882b9ca89 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -960,11 +960,47 @@ ValPtr BinaryExpr::Fold(Val* v1, Val* v2) const DO_UINT_FOLD(^); break; case EXPR_LSHIFT: - DO_INT_FOLD(<<); + { + if ( is_integral ) + { + if ( i2 < 0 ) + RuntimeError("left shift by negative value"); + else if ( i1 < 1 ) + RuntimeError("left shifting a negative number is undefined"); + + i3 = i1 << i2; + } + else if ( is_unsigned ) + { + if ( u2 < 0 ) + RuntimeError("left shift by negative value"); + + u3 = u1 << u2; + } + else + RuntimeErrorWithCallStack("bad type in BinaryExpr::Fold"); break; + } case EXPR_RSHIFT: - DO_INT_FOLD(>>); + { + if ( is_integral ) + { + if ( i2 < 0 ) + RuntimeError("right shift by negative value"); + + i3 = i1 >> i2; + } + else if ( is_unsigned ) + { + if ( u2 < 0 ) + RuntimeError("right shift by negative value"); + + u3 = u1 >> u2; + } + else + RuntimeErrorWithCallStack("bad type in BinaryExpr::Fold"); break; + } case EXPR_AND_AND: DO_INT_FOLD(&&); diff --git a/testing/btest/Baseline/language.int/out b/testing/btest/Baseline/language.int/out index b2f4f2c04a..f01f5a3de1 100644 --- a/testing/btest/Baseline/language.int/out +++ b/testing/btest/Baseline/language.int/out @@ -18,6 +18,7 @@ modulus operator (PASS) division operator (PASS) assignment operator (PASS) assignment operator (PASS) +bitwise lshift (PASS) bitwise rshift (PASS) max int value = 9223372036854775807 (PASS) min int value = -9223372036854775808 (PASS) diff --git a/testing/btest/language/int.zeek b/testing/btest/language/int.zeek index 1f010e8048..469cd56e07 100644 --- a/testing/btest/language/int.zeek +++ b/testing/btest/language/int.zeek @@ -54,7 +54,8 @@ event zeek_init() test_case( "assignment operator", i2 == 7 ); i2 -= 2; test_case( "assignment operator", i2 == 5 ); - test_case( "bitwise rshift", i10 >> 1 == -6 ); + test_case( "bitwise lshift", i6 << 1 == 24 ); + test_case( "bitwise rshift", i6 >> 1 == 6 ); # Max/min value tests @@ -68,4 +69,3 @@ event zeek_init() test_case( str4, str4 == "min int value = -9223372036854775808" ); } - diff --git a/testing/btest/language/vector.zeek b/testing/btest/language/vector.zeek index 5c72c31986..7c461b4ce0 100644 --- a/testing/btest/language/vector.zeek +++ b/testing/btest/language/vector.zeek @@ -226,4 +226,9 @@ event zeek_init() v21[3:] = vector(); print "hole in vector of managed types after replacing slice", |v21|, v21; + # Test << and >> operators. + local v22 = v6 << 1; + local v23 = v6 >> 1; + test_case( "left shift", all_set(v22 == vector(20, 40, 60)) ); + test_case( "right shift", all_set(v23 == vector(5, 10, 15)) ); }