From 8fff3c76b9b1e7de4aa9b0cdb0989c72a88b15fc Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 21 Jul 2022 13:03:16 -0700 Subject: [PATCH 1/2] Handle error cases for bit-shift operators more cleanly --- src/Expr.cc | 40 +++++++++++++++++++++++-- testing/btest/Baseline/language.int/out | 1 + testing/btest/language/int.zeek | 4 +-- 3 files changed, 41 insertions(+), 4 deletions(-) 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" ); } - From 25f88bc394e0692074ceddabf96e5da7eefd980e Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 21 Jul 2022 13:12:57 -0700 Subject: [PATCH 2/2] Add btest for vector bit-shift operators --- testing/btest/language/vector.zeek | 5 +++++ 1 file changed, 5 insertions(+) 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)) ); }