diff --git a/src/Expr.cc b/src/Expr.cc index 39dc91b565..85ab7b5d26 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1287,25 +1287,6 @@ void BinaryExpr::PromoteForInterval(ExprPtr& op) op = make_intrusive(op, TYPE_DOUBLE); } -bool BinaryExpr::IsScalarAggregateOp() const - { - const bool is_vec1 = IsAggr(op1->GetType()->Tag()) || is_list(op1); - const bool is_vec2 = IsAggr(op2->GetType()->Tag()) || is_list(op2); - const bool either_vec = is_vec1 || is_vec2; - const bool both_vec = is_vec1 && is_vec2; - - return either_vec && ! both_vec; - } - -void BinaryExpr::CheckScalarAggOp() const - { - if ( ! IsError() && IsScalarAggregateOp() ) - { - reporter->Warning("mixing vector and scalar operands is deprecated (%s) (%s)", - type_name(op1->GetType()->Tag()), type_name(op2->GetType()->Tag())); - } - } - bool BinaryExpr::CheckForRHSList() { if ( op2->Tag() != EXPR_LIST ) @@ -1420,24 +1401,10 @@ IncrExpr::IncrExpr(ExprTag arg_tag, ExprPtr arg_op) : UnaryExpr(arg_tag, arg_op- return; const auto& t = op->GetType(); - - if ( IsVector(t->Tag()) ) - { - if ( ! IsIntegral(t->AsVectorType()->Yield()->Tag()) ) - ExprError("vector elements must be integral for increment operator"); - else - { - reporter->Warning("increment/decrement operations for vectors deprecated"); - SetType(t); - } - } + if ( ! IsIntegral(t->Tag()) ) + ExprError("requires an integral operand"); else - { - if ( ! IsIntegral(t->Tag()) ) - ExprError("requires an integral operand"); - else - SetType(t); - } + SetType(t); } ValPtr IncrExpr::DoSingleEval(Frame* f, Val* v) const @@ -1469,26 +1436,9 @@ ValPtr IncrExpr::Eval(Frame* f) const if ( ! v ) return nullptr; - if ( is_vector(v) ) - { - VectorValPtr v_vec{NewRef{}, v->AsVectorVal()}; - - for ( unsigned int i = 0; i < v_vec->Size(); ++i ) - { - auto elt = v_vec->ValAt(i); - if ( elt ) - v_vec->Assign(i, DoSingleEval(f, elt.get())); - } - - op->Assign(f, std::move(v_vec)); - return v; - } - else - { - auto new_v = DoSingleEval(f, v.get()); - op->Assign(f, new_v); - return new_v; - } + auto new_v = DoSingleEval(f, v.get()); + op->Assign(f, new_v); + return new_v; } ComplementExpr::ComplementExpr(ExprPtr arg_op) : UnaryExpr(EXPR_COMPLEMENT, std::move(arg_op)) @@ -1634,14 +1584,18 @@ AddExpr::AddExpr(ExprPtr arg_op1, ExprPtr arg_op2) return; TypeTag bt1 = op1->GetType()->Tag(); - - if ( IsVector(bt1) ) - bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); - if ( IsVector(bt2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } TypePtr base_result_type; @@ -1656,11 +1610,9 @@ AddExpr::AddExpr(ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("requires arithmetic operands"); - CheckScalarAggOp(); - if ( base_result_type ) { - if ( is_vector(op1) || is_vector(op2) ) + if ( is_vector(op1) ) SetType(make_intrusive(std::move(base_result_type))); else SetType(std::move(base_result_type)); @@ -1798,12 +1750,18 @@ SubExpr::SubExpr(ExprPtr arg_op1, ExprPtr arg_op2) const auto& t2 = op2->GetType(); TypeTag bt1 = t1->Tag(); - if ( IsVector(bt1) ) - bt1 = t1->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = t2->Tag(); - if ( IsVector(bt2) ) + + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = t1->AsVectorType()->Yield()->Tag(); bt2 = t2->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } TypePtr base_result_type; @@ -1827,11 +1785,9 @@ SubExpr::SubExpr(ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("requires arithmetic operands"); - CheckScalarAggOp(); - if ( base_result_type ) { - if ( is_vector(op1) || is_vector(op2) ) + if ( is_vector(op1) ) SetType(make_intrusive(std::move(base_result_type))); else SetType(std::move(base_result_type)); @@ -1902,14 +1858,18 @@ TimesExpr::TimesExpr(ExprPtr arg_op1, ExprPtr arg_op2) Canonicalize(); TypeTag bt1 = op1->GetType()->Tag(); - - if ( IsVector(bt1) ) - bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); - if ( IsVector(bt2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } if ( bt1 == TYPE_INTERVAL || bt2 == TYPE_INTERVAL ) { @@ -1922,8 +1882,6 @@ TimesExpr::TimesExpr(ExprPtr arg_op1, ExprPtr arg_op2) PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); else ExprError("requires arithmetic operands"); - - CheckScalarAggOp(); } void TimesExpr::Canonicalize() @@ -1940,14 +1898,18 @@ DivideExpr::DivideExpr(ExprPtr arg_op1, ExprPtr arg_op2) return; TypeTag bt1 = op1->GetType()->Tag(); - - if ( IsVector(bt1) ) - bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); - if ( IsVector(bt2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } if ( bt1 == TYPE_INTERVAL || bt2 == TYPE_INTERVAL ) { @@ -1972,8 +1934,6 @@ DivideExpr::DivideExpr(ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("requires arithmetic operands"); - - CheckScalarAggOp(); } ValPtr DivideExpr::AddrFold(Val* v1, Val* v2) const @@ -2008,21 +1968,23 @@ ModExpr::ModExpr(ExprPtr arg_op1, ExprPtr arg_op2) return; TypeTag bt1 = op1->GetType()->Tag(); - - if ( IsVector(bt1) ) - bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); - if ( IsVector(bt2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } if ( BothIntegral(bt1, bt2) ) PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); else ExprError("requires integral operands"); - - CheckScalarAggOp(); } BoolExpr::BoolExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) @@ -2032,23 +1994,23 @@ BoolExpr::BoolExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) return; TypeTag bt1 = op1->GetType()->Tag(); - - if ( IsVector(bt1) ) - bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); - if ( IsVector(bt2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } if ( BothBool(bt1, bt2) ) { - if ( is_vector(op1) || is_vector(op2) ) - { - if ( ! (is_vector(op1) && is_vector(op2)) ) - reporter->Warning("mixing vector and scalar operands is deprecated"); + if ( is_vector(op1) ) SetType(make_intrusive(base_type(TYPE_BOOL))); - } else SetType(base_type(TYPE_BOOL)); } @@ -2095,46 +2057,7 @@ ValPtr BoolExpr::Eval(Frame* f) const if ( ! is_vec1 && ! is_vec2 ) return DoSingleEval(f, std::move(v1), op2.get()); - // Handle scalar op vector or vector op scalar - // We can't short-circuit everything since we need to eval - // a vector in order to find out its length. - if ( ! (is_vec1 && is_vec2) ) - { // Only one is a vector. - ValPtr scalar_v; - VectorValPtr vector_v; - - if ( is_vec1 ) - { - scalar_v = op2->Eval(f); - vector_v = {AdoptRef{}, v1.release()->AsVectorVal()}; - } - else - { - scalar_v = std::move(v1); - vector_v = {AdoptRef{}, op2->Eval(f).release()->AsVectorVal()}; - } - - if ( ! scalar_v || ! vector_v ) - return nullptr; - - VectorValPtr result; - - // It's either an EXPR_AND_AND or an EXPR_OR_OR. - bool is_and = (tag == EXPR_AND_AND); - - if ( scalar_v->IsZero() == is_and ) - { - result = make_intrusive(GetType()); - result->Resize(vector_v->Size()); - result->AssignRepeat(0, result->Size(), std::move(scalar_v)); - } - else - result = std::move(vector_v); - - return result; - } - - // Only case remaining: both are vectors. + // Both are vectors. auto v2 = op2->Eval(f); if ( ! v2 ) @@ -2206,8 +2129,6 @@ BitExpr::BitExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) return; // because following scalar check isn't apt } - CheckScalarAggOp(); - if ( (bt1 == TYPE_COUNT) && (bt2 == TYPE_COUNT) ) { if ( is_vector(op1) || is_vector(op2) ) @@ -2248,16 +2169,21 @@ EqExpr::EqExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) const auto& t1 = op1->GetType(); const auto& t2 = op2->GetType(); - TypeTag bt1 = t1->Tag(); - if ( IsVector(bt1) ) - bt1 = t1->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = t2->Tag(); - if ( IsVector(bt2) ) - bt2 = t2->AsVectorType()->Yield()->Tag(); - if ( is_vector(op1) || is_vector(op2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = t1->AsVectorType()->Yield()->Tag(); + bt2 = t2->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } + + if ( is_vector(op1) ) SetType(make_intrusive(base_type(TYPE_BOOL))); else SetType(base_type(TYPE_BOOL)); @@ -2310,8 +2236,6 @@ EqExpr::EqExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("type clash in comparison"); - - CheckScalarAggOp(); } void EqExpr::Canonicalize() @@ -2363,16 +2287,21 @@ RelExpr::RelExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) const auto& t1 = op1->GetType(); const auto& t2 = op2->GetType(); - TypeTag bt1 = t1->Tag(); - if ( IsVector(bt1) ) - bt1 = t1->AsVectorType()->Yield()->Tag(); - TypeTag bt2 = t2->Tag(); - if ( IsVector(bt2) ) - bt2 = t2->AsVectorType()->Yield()->Tag(); - if ( is_vector(op1) || is_vector(op2) ) + if ( IsVector(bt1) && IsVector(bt2) ) + { + bt1 = t1->AsVectorType()->Yield()->Tag(); + bt2 = t2->AsVectorType()->Yield()->Tag(); + } + else if ( IsVector(bt1) || IsVector(bt2) ) + { + ExprError("cannot mix vector and scalar operands"); + return; + } + + if ( is_vector(op1) ) SetType(make_intrusive(base_type(TYPE_BOOL))); else SetType(base_type(TYPE_BOOL)); @@ -2392,8 +2321,6 @@ RelExpr::RelExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) else if ( bt1 != TYPE_TIME && bt1 != TYPE_INTERVAL && bt1 != TYPE_PORT && bt1 != TYPE_ADDR && bt1 != TYPE_STRING ) ExprError("illegal comparison"); - - CheckScalarAggOp(); } void RelExpr::Canonicalize() diff --git a/src/Expr.h b/src/Expr.h index 329ef58a73..f73b8f30d8 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -624,14 +624,6 @@ protected: void ExprDescribe(ODesc* d) const override; - // Reports on if this BinaryExpr involves a scalar and aggregate - // type (vec, list, table, record). - bool IsScalarAggregateOp() const; - - // Warns about deprecated scalar vector operations like - // `[1, 2, 3] == 1` or `["a", "b", "c"] + "a"`. - void CheckScalarAggOp() const; - // For assignment operations (=, +=, -=) checks for a valid // expression-list on the RHS (op2), potentially transforming // op2 in the process. Returns true if the list is present diff --git a/testing/btest/Baseline/core.scalar-vector/out b/testing/btest/Baseline/core.scalar-vector/out deleted file mode 100644 index 9de4185db8..0000000000 --- a/testing/btest/Baseline/core.scalar-vector/out +++ /dev/null @@ -1,16 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/scalar-vector.zeek, line 12: mixing vector and scalar operands is deprecated (string) (vector) -warning in <...>/scalar-vector.zeek, line 13: mixing vector and scalar operands is deprecated (vector) (string) -warning in <...>/scalar-vector.zeek, line 14: mixing vector and scalar operands is deprecated (string) (vector) -warning in <...>/scalar-vector.zeek, line 18: mixing vector and scalar operands is deprecated (count) (vector) -warning in <...>/scalar-vector.zeek, line 19: mixing vector and scalar operands is deprecated (count) (vector) -warning in <...>/scalar-vector.zeek, line 20: mixing vector and scalar operands is deprecated (vector) (count) -warning in <...>/scalar-vector.zeek, line 21: mixing vector and scalar operands is deprecated (vector) (count) -[F, T, F] -[aa, ba, ca] -[aa, ab, ac] -[F, T, F] -[2, 4, 6] -[1, 0, 1] -[0, 1, 1] -[1, 2, 3, 1] diff --git a/testing/btest/Baseline/language.incr-vec-expr-error/out b/testing/btest/Baseline/language.incr-vec-expr-error/out new file mode 100644 index 0000000000..d94a36e72f --- /dev/null +++ b/testing/btest/Baseline/language.incr-vec-expr-error/out @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/incr-vec-expr-error.test, line 16: requires an integral operand (++vec) +error in <...>/incr-vec-expr-error.test, line 17: requires an integral operand (++v$c) diff --git a/testing/btest/Baseline/language.incr-vec-expr/out b/testing/btest/Baseline/language.incr-vec-expr/out deleted file mode 100644 index 2ac978efeb..0000000000 --- a/testing/btest/Baseline/language.incr-vec-expr/out +++ /dev/null @@ -1,6 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[0, 0, 0] -[a=0, b=test, c=[1, 2, 3]] -[1, 1, 1] -[a=1, b=test, c=[1, 2, 3]] -[a=1, b=test, c=[2, 3, 4]] diff --git a/testing/btest/Baseline/language.vector-deprecated/.stderr b/testing/btest/Baseline/language.vector-deprecated/.stderr deleted file mode 100644 index 2cce0f6b82..0000000000 --- a/testing/btest/Baseline/language.vector-deprecated/.stderr +++ /dev/null @@ -1,4 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/vector-deprecated.zeek, line 19: mixing vector and scalar operands is deprecated (vector) (string) -warning in <...>/vector-deprecated.zeek, line 22: mixing vector and scalar operands is deprecated (string) (vector) -warning in <...>/vector-deprecated.zeek, line 25: mixing vector and scalar operands is deprecated (string) (vector) diff --git a/testing/btest/Baseline/language.vector-deprecated/out b/testing/btest/Baseline/language.vector-deprecated/out deleted file mode 100644 index c5cb1b1f1a..0000000000 --- a/testing/btest/Baseline/language.vector-deprecated/out +++ /dev/null @@ -1,4 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -+ operator [string] (PASS) -== operator [string] (PASS) -== operator [string] (PASS) diff --git a/testing/btest/core/scalar-vector.zeek b/testing/btest/core/scalar-vector.zeek deleted file mode 100644 index e5bcc44431..0000000000 --- a/testing/btest/core/scalar-vector.zeek +++ /dev/null @@ -1,25 +0,0 @@ -# Skip this test when using script optimization, as that generate hard -# errors in addition to warnings. -# @TEST-REQUIRES: test "${ZEEK_ZAM}" != "1" -# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1" -# -# @TEST-EXEC: zeek -b %INPUT > out 2>&1 -# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath" btest-diff out - -event zeek_init() - { - const sv = vector("a", "b", "c"); - print sv == "b"; - print sv + "a"; - print "a" + sv; - - - const nv = vector(1, 2, 3); - print nv == 2; - print nv * 2; - print nv % 2; - print nv / 2; - - const also_nv = nv += 1; - print nv; - } diff --git a/testing/btest/language/incr-vec-expr-error.test b/testing/btest/language/incr-vec-expr-error.test new file mode 100644 index 0000000000..f261778737 --- /dev/null +++ b/testing/btest/language/incr-vec-expr-error.test @@ -0,0 +1,17 @@ +# @TEST-DOC: Support for incrementing vectors using IncrExpr has been removed. +# @TEST-EXEC-FAIL: zeek -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +type rec: record { + a: count; + b: string; + c: vector of count; +}; + +global vec: vector of count = vector(0,0,0); + +global v: rec = [$a=0, $b="test", $c=vector(1,2,3)]; + +++v$a; +++vec; +++v$c; diff --git a/testing/btest/language/incr-vec-expr.test b/testing/btest/language/incr-vec-expr.test deleted file mode 100644 index 7831f2292b..0000000000 --- a/testing/btest/language/incr-vec-expr.test +++ /dev/null @@ -1,28 +0,0 @@ -# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1" -# @TEST-EXEC: zeek -b %INPUT >out -# @TEST-EXEC: btest-diff out - -type rec: record { - a: count; - b: string; - c: vector of count; -}; - -global vec: vector of count = vector(0,0,0); - -global v: rec = [$a=0, $b="test", $c=vector(1,2,3)]; - -print vec; -print v; - -++vec; - -print vec; - -++v$a; - -print v; - -++v$c; - -print v; diff --git a/testing/btest/language/vector-deprecated.zeek b/testing/btest/language/vector-deprecated.zeek deleted file mode 100644 index 2e3d87f841..0000000000 --- a/testing/btest/language/vector-deprecated.zeek +++ /dev/null @@ -1,28 +0,0 @@ -# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1" -# @TEST-EXEC: zeek -b %INPUT >out -# @TEST-EXEC: btest-diff out -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr - -function test_case(msg: string, expect: bool) - { - print fmt("%s (%s)", msg, expect ? "PASS" : "FAIL"); - } - -event zeek_init() -{ - local v6 = vector( 10, 20, 30 ); - local v16 = v6; - v16 += 40; - - local vs1 = vector( "foo", "bar" ); - - local vss2 = vs1 + "@"; - test_case( "+ operator [string]", vss2[0] == "foo@" && vss2[1] == "bar@" ); - - local vss4 = (vs1 == "bar"); - test_case( "== operator [string]", vss4[0] == F && vss4[1] == T ); - - local vss5 = ("bar" == vs1); - test_case( "== operator [string]", vss5[0] == F && vss5[1] == T ); - # !=, <, >, <=, >= are handled the same as ==, skipping tests -} diff --git a/testing/btest/language/vector-in-operator.zeek b/testing/btest/language/vector-in-operator.zeek index e8cb455dc9..bd76c5df4b 100644 --- a/testing/btest/language/vector-in-operator.zeek +++ b/testing/btest/language/vector-in-operator.zeek @@ -8,7 +8,9 @@ local n = 0; vec[5] = "five"; vec[7] = "seven"; print vec; -vec = vec + ".exe"; + +for ( i in vec ) + vec[i] += ".exe"; for ( c in ten ) {