diff --git a/src/parse.y b/src/parse.y index d0eeb91300..65d13a438d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -330,6 +330,36 @@ expr: { zeek::detail::set_location(@1, @2); $$ = new zeek::detail::NegExpr({zeek::AdoptRef{}, $2}); + + if ( ! $$->IsError() && $2->IsConst() ) + { + auto v = $2->ExprVal(); + auto tag = v->GetType()->Tag(); + + if ( tag == zeek::TYPE_COUNT ) + { + auto c = v->AsCount(); + uint64_t int_max = static_cast(INT64_MAX) + 1; + + if ( c <= int_max ) + { + auto ce = new zeek::detail::ConstExpr(zeek::val_mgr->Int(-c)); + Unref($$); + $$ = ce; + } + else + { + $$->Error("literal is outside range of 'int' values"); + $$->SetError(); + } + } + else + { + auto ce = new zeek::detail::ConstExpr($$->Eval(nullptr)); + Unref($$); + $$ = ce; + } + } } | '+' expr %prec '!' diff --git a/testing/btest/Baseline/language.int-negation-range/out b/testing/btest/Baseline/language.int-negation-range/out new file mode 100644 index 0000000000..161e8467b5 --- /dev/null +++ b/testing/btest/Baseline/language.int-negation-range/out @@ -0,0 +1,2 @@ +error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.int-negation-range/int-negation-range.zeek, line 8: literal is outside range of 'int' values (-9223372036854775809) +error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.int-negation-range/int-negation-range.zeek, line 9: literal is outside range of 'int' values (-9223372036854775810) diff --git a/testing/btest/language/int-negation-range.zeek b/testing/btest/language/int-negation-range.zeek new file mode 100644 index 0000000000..ae7b4ede3f --- /dev/null +++ b/testing/btest/language/int-negation-range.zeek @@ -0,0 +1,9 @@ +# @TEST-EXEC-FAIL: zeek -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +local i_min = -9223372036854775808; +local i_min_p1 = -9223372036854775807; + +# These should be caught at parse-time as outside the range of a 64-bit ints. +local i_min_m1 = -9223372036854775809; +local i_min_m2 = -9223372036854775810;