From baf2a91a8529046dd192cbf77a8ddca587e2500e Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 22 Nov 2022 13:01:10 -0800 Subject: [PATCH] Type coercion fix: transform +=/-= operators with arithmetic targets to explict assignments --- src/parse.y | 34 +++++++++++++++++-- .../Baseline/language.init-mismatch/.stderr | 2 +- .../first_set.err | 2 +- .../first_set.out | 4 +++ testing/btest/Baseline/plugins.hooks/output | 18 +++++----- .../btest/language/type-coerce-numerics.zeek | 8 +++++ 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/parse.y b/src/parse.y index 2d06d662ca..c386a5e831 100644 --- a/src/parse.y +++ b/src/parse.y @@ -572,7 +572,22 @@ expr: | expr TOK_ADD_TO rhs { set_location(@1, @3); - $$ = new AddToExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); + + ExprPtr lhs = {AdoptRef{}, $1}; + ExprPtr rhs = {AdoptRef{}, $3}; + auto tag1 = $1->GetType()->Tag(); + + if ( IsArithmetic($1->GetType()->Tag()) ) + { + ExprPtr sum = make_intrusive(lhs, rhs); + + if ( sum->GetType()->Tag() != tag1 ) + sum = make_intrusive(sum, tag1); + + $$ = new AssignExpr(lhs, sum, false); + } + else + $$ = new AddToExpr(lhs, rhs); } | expr '-' expr @@ -584,7 +599,22 @@ expr: | expr TOK_REMOVE_FROM rhs { set_location(@1, @3); - $$ = new RemoveFromExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); + + ExprPtr lhs = {AdoptRef{}, $1}; + ExprPtr rhs = {AdoptRef{}, $3}; + auto tag1 = $1->GetType()->Tag(); + + if ( IsArithmetic(tag1) ) + { + ExprPtr sum = make_intrusive(lhs, rhs); + + if ( sum->GetType()->Tag() != tag1 ) + sum = make_intrusive(sum, tag1); + + $$ = new AssignExpr(lhs, sum, false); + } + else + $$ = new RemoveFromExpr(lhs, rhs); } | expr '*' expr diff --git a/testing/btest/Baseline/language.init-mismatch/.stderr b/testing/btest/Baseline/language.init-mismatch/.stderr index ee09bb0b27..d65bba4b4a 100644 --- a/testing/btest/Baseline/language.init-mismatch/.stderr +++ b/testing/btest/Baseline/language.init-mismatch/.stderr @@ -7,7 +7,7 @@ error in <...>/init-mismatch.zeek, line 14: table constructor element lacks '=' error in <...>/init-mismatch.zeek, line 17: empty list in untyped initialization () error in <...>/init-mismatch.zeek, line 23: cannot expand constructor elements using a value that depends on local variables (subnets) error in <...>/init-mismatch.zeek, line 23: type clash in assignment (my_subnets = set(foo, subnets)) -error in <...>/init-mismatch.zeek, line 26: invalid constructor list on RHS of assignment (c += 2, 4) +error in <...>/init-mismatch.zeek, line 26: requires arithmetic operands (c + 2, 4) error in <...>/init-mismatch.zeek, line 27: constructor list not allowed for -= operations on vectors (v -= 3, 5) error in <...>/init-mismatch.zeek, line 29: RHS type mismatch for table/set += (s1 += s2) error in <...>/init-mismatch.zeek, line 30: RHS type mismatch for table/set -= (s1 -= s2) diff --git a/testing/btest/Baseline/language.type-coerce-numerics/first_set.err b/testing/btest/Baseline/language.type-coerce-numerics/first_set.err index 29b7649157..ed6d76e321 100644 --- a/testing/btest/Baseline/language.type-coerce-numerics/first_set.err +++ b/testing/btest/Baseline/language.type-coerce-numerics/first_set.err @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in int and ./first_set.zeek, line 46: overflow promoting from unsigned/double to signed arithmetic value (int and 9223372036854775808) +error in int and ./first_set.zeek, line 54: overflow promoting from unsigned/double to signed arithmetic value (int and 9223372036854775808) diff --git a/testing/btest/Baseline/language.type-coerce-numerics/first_set.out b/testing/btest/Baseline/language.type-coerce-numerics/first_set.out index b31869c4eb..bbf5d32087 100644 --- a/testing/btest/Baseline/language.type-coerce-numerics/first_set.out +++ b/testing/btest/Baseline/language.type-coerce-numerics/first_set.out @@ -11,3 +11,7 @@ int double -5.0 double +7 +count +10 +count diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index f6098e74b3..4a342935ff 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -677,17 +677,17 @@ 0.000000 MetaHookPost CallFunction(Site::update_neighbor_zones_regex, , (Site::neighbor_zones, {})) -> 0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, , (SumStats::STD_DEV, SumStats::VARIANCE)) -> 0.000000 MetaHookPost CallFunction(SumStats::add_observe_plugin_dependency, , (SumStats::VARIANCE, SumStats::AVERAGE)) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::AVERAGE, lambda_<3452231521688988155>{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::AVERAGE, lambda_<11942714483660580348>{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average = SumStats::rv$average + (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::HLL_UNIQUE, lambda_<11844992922323210106>{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, to_any_coerceSumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::LAST, lambda_<7814612727898186946>{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, to_any_coerceSumStats::obs)}})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::MAX, lambda_<9734000075919044397>{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::MIN, lambda_<2451066605226214733>{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::SAMPLE, lambda_<11888441397542569241>{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<7459411543525688824>{ SumStats::rv$sum = SumStats::rv$sum + SumStats::val})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<6609886180724383051>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<5978956599776442208>{ if (1 < SumStats::rv$num) SumStats::rv$var_s = SumStats::rv$var_s + ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, , ()) -> 0.000000 MetaHookPost CallFunction(Supervisor::__is_supervisor, , ()) -> 0.000000 MetaHookPost CallFunction(Supervisor::is_supervisor, , ()) -> @@ -2193,17 +2193,17 @@ 0.000000 MetaHookPre CallFunction(Site::update_neighbor_zones_regex, , (Site::neighbor_zones, {})) 0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, , (SumStats::STD_DEV, SumStats::VARIANCE)) 0.000000 MetaHookPre CallFunction(SumStats::add_observe_plugin_dependency, , (SumStats::VARIANCE, SumStats::AVERAGE)) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::AVERAGE, lambda_<3452231521688988155>{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::AVERAGE, lambda_<11942714483660580348>{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average = SumStats::rv$average + (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::HLL_UNIQUE, lambda_<11844992922323210106>{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, to_any_coerceSumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::LAST, lambda_<7814612727898186946>{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, to_any_coerceSumStats::obs)}})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::MAX, lambda_<9734000075919044397>{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::MIN, lambda_<2451066605226214733>{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::SAMPLE, lambda_<11888441397542569241>{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<7459411543525688824>{ SumStats::rv$sum = SumStats::rv$sum + SumStats::val})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<6609886180724383051>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<5978956599776442208>{ if (1 < SumStats::rv$num) SumStats::rv$var_s = SumStats::rv$var_s + ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugins, , ()) 0.000000 MetaHookPre CallFunction(Supervisor::__is_supervisor, , ()) 0.000000 MetaHookPre CallFunction(Supervisor::is_supervisor, , ()) @@ -3708,17 +3708,17 @@ 0.000000 | HookCallFunction Site::update_neighbor_zones_regex(Site::neighbor_zones, {}) 0.000000 | HookCallFunction SumStats::add_observe_plugin_dependency(SumStats::STD_DEV, SumStats::VARIANCE) 0.000000 | HookCallFunction SumStats::add_observe_plugin_dependency(SumStats::VARIANCE, SumStats::AVERAGE) -0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::AVERAGE, lambda_<3452231521688988155>{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average += (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::AVERAGE, lambda_<11942714483660580348>{ if (!SumStats::rv?$average) SumStats::rv$average = SumStats::valelseSumStats::rv$average = SumStats::rv$average + (SumStats::val - SumStats::rv$average) / (coerce SumStats::rv$num to double)}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::HLL_UNIQUE, lambda_<11844992922323210106>{ if (!SumStats::rv?$card) { SumStats::rv$card = hll_cardinality_init(SumStats::r$hll_error_margin, SumStats::r$hll_confidence)SumStats::rv$hll_error_margin = SumStats::r$hll_error_marginSumStats::rv$hll_confidence = SumStats::r$hll_confidence}hll_cardinality_add(SumStats::rv$card, to_any_coerceSumStats::obs)SumStats::rv$hll_unique = double_to_count(hll_cardinality_estimate(SumStats::rv$card))}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::LAST, lambda_<7814612727898186946>{ if (0 < SumStats::r$num_last_elements) { if (!SumStats::rv?$last_elements) SumStats::rv$last_elements = Queue::init((coerce [$max_len=SumStats::r$num_last_elements] to Queue::Settings))Queue::put(SumStats::rv$last_elements, to_any_coerceSumStats::obs)}}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::MAX, lambda_<9734000075919044397>{ if (!SumStats::rv?$max) SumStats::rv$max = SumStats::valelseif (SumStats::rv$max < SumStats::val) SumStats::rv$max = SumStats::val}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::MIN, lambda_<2451066605226214733>{ if (!SumStats::rv?$min) SumStats::rv$min = SumStats::valelseif (SumStats::val < SumStats::rv$min) SumStats::rv$min = SumStats::val}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SAMPLE, lambda_<11888441397542569241>{ SumStats::sample_add_sample(SumStats::obs, SumStats::rv)}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)}) -0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SUM, lambda_<7459411543525688824>{ SumStats::rv$sum = SumStats::rv$sum + SumStats::val}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::UNIQUE, lambda_<6609886180724383051>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals}) -0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::VARIANCE, lambda_<5978956599776442208>{ if (1 < SumStats::rv$num) SumStats::rv$var_s = SumStats::rv$var_s + ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average}) 0.000000 | HookCallFunction SumStats::register_observe_plugins() 0.000000 | HookCallFunction Supervisor::__is_supervisor() 0.000000 | HookCallFunction Supervisor::is_supervisor() diff --git a/testing/btest/language/type-coerce-numerics.zeek b/testing/btest/language/type-coerce-numerics.zeek index 80e475ae12..561b3d5c0d 100644 --- a/testing/btest/language/type-coerce-numerics.zeek +++ b/testing/btest/language/type-coerce-numerics.zeek @@ -63,6 +63,14 @@ event zeek_init() local doubleconvert2 = myrecord($dd = -5); print(doubleconvert2$dd); print(type_name(doubleconvert2$dd)); + + local cnt = 5; + cnt += +2; + print cnt; + print type_name(cnt); + cnt -= -3; + print cnt; + print type_name(cnt); } event zeek_init()