diff --git a/doc b/doc index 9e77250acc..d8ddfa0468 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 9e77250acc4b5eaf03c0535e8ea00a0a4d19cae0 +Subproject commit d8ddfa04683d6b062cbb22b1198163748a45aade diff --git a/scripts/base/frameworks/netcontrol/non-cluster.zeek b/scripts/base/frameworks/netcontrol/non-cluster.zeek index e1363fd883..3099d0c840 100644 --- a/scripts/base/frameworks/netcontrol/non-cluster.zeek +++ b/scripts/base/frameworks/netcontrol/non-cluster.zeek @@ -28,7 +28,7 @@ event rule_expire(r: Rule, p: PluginState) &priority=-5 rule_expire_impl(r, p); } -event rule_exists(r: Rule, p: PluginState, msg: string &default="") &priority=5 +event rule_exists(r: Rule, p: PluginState, msg: string) &priority=5 { rule_added_impl(r, p, T, msg); @@ -36,7 +36,7 @@ event rule_exists(r: Rule, p: PluginState, msg: string &default="") &priority=5 schedule r$expire { rule_expire(r, p) }; } -event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 +event rule_added(r: Rule, p: PluginState, msg: string) &priority=5 { rule_added_impl(r, p, F, msg); @@ -44,7 +44,7 @@ event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 schedule r$expire { rule_expire(r, p) }; } -event rule_removed(r: Rule, p: PluginState, msg: string &default="") &priority=-5 +event rule_removed(r: Rule, p: PluginState, msg: string) &priority=-5 { rule_removed_impl(r, p, msg); } @@ -54,7 +54,7 @@ event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) &priority=-5 rule_timeout_impl(r, i, p); } -event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5 +event rule_error(r: Rule, p: PluginState, msg: string) &priority=-5 { rule_error_impl(r, p, msg); } diff --git a/scripts/policy/frameworks/netcontrol/catch-and-release.zeek b/scripts/policy/frameworks/netcontrol/catch-and-release.zeek index b11170929f..c0182bd5bf 100644 --- a/scripts/policy/frameworks/netcontrol/catch-and-release.zeek +++ b/scripts/policy/frameworks/netcontrol/catch-and-release.zeek @@ -259,7 +259,7 @@ function cr_check_rule(r: Rule): bool @if ( ! Cluster::is_enabled() || ( Cluster::is_enabled() && Cluster::local_node_type() == Cluster::MANAGER ) ) -event rule_added(r: Rule, p: PluginState, msg: string &default="") +event rule_added(r: Rule, p: PluginState, msg: string) { if ( !cr_check_rule(r) ) return; diff --git a/src/Var.cc b/src/Var.cc index caa599ed6b..adc57d2a79 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -471,22 +471,46 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, if ( id->Type() ) { - prototype = func_type_check(id->Type()->AsFuncType(), t.get()); + auto decl = id->Type()->AsFuncType(); + prototype = func_type_check(decl, t.get()); if ( prototype ) { - // If a previous declaration of the function had &default params, - // automatically transfer any that are missing (convenience so that - // implementations don't need to specify the &default expression again). - transfer_arg_defaults(prototype->args.get(), t->Args()); + if ( decl->Flavor() == FUNC_FLAVOR_FUNCTION ) + { + // If a previous declaration of the function had &default + // params, automatically transfer any that are missing + // (convenience so that implementations don't need to specify + // the &default expression again). + transfer_arg_defaults(prototype->args.get(), t->Args()); + } + else + { + // Warn for trying to use &default parameters in hook/event + // handler body when it already has a declaration since only + // &default in the declaration has any effect. + auto args = t->Args(); + + for ( int i = 0; i < args->NumFields(); ++i ) + { + auto f = args->FieldDecl(i); + + if ( f->attrs && f->attrs->FindAttr(ATTR_DEFAULT) ) + { + reporter->PushLocation(args->GetLocationInfo()); + reporter->Warning( + "&default on parameter '%s' has no effect (not a %s declaration)", + args->FieldName(i), t->FlavorString().data()); + reporter->PopLocation(); + } + } + } if ( prototype->deprecated ) t->Warn("use of deprecated prototype", id); } else { - auto decl = id->Type()->AsFuncType(); - // Allow renaming arguments, but only for the canonical // prototypes of hooks/events. if ( canonical_arg_types_match(decl, t.get()) ) diff --git a/testing/btest/Baseline/language.ineffective-default-args/out b/testing/btest/Baseline/language.ineffective-default-args/out new file mode 100644 index 0000000000..1d7e508a4f --- /dev/null +++ b/testing/btest/Baseline/language.ineffective-default-args/out @@ -0,0 +1,8 @@ +warning in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.ineffective-default-args/ineffective-default-args.zeek, line 9: &default on parameter 'b' has no effect (not a event declaration) +warning in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.ineffective-default-args/ineffective-default-args.zeek, line 19: &default on parameter 'c' has no effect (not a event declaration) +bar, A, B +baz, A, B +qux, Q, Q +grault, A, B +corge, C +foo c, C diff --git a/testing/btest/language/ineffective-default-args.zeek b/testing/btest/language/ineffective-default-args.zeek new file mode 100644 index 0000000000..2fff7dcda2 --- /dev/null +++ b/testing/btest/language/ineffective-default-args.zeek @@ -0,0 +1,54 @@ +# @TEST-EXEC: zeek -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +global grault: event(a: string, b: string &default="B"); + +global foo: event(a: string, b: string, c: string &default="C"); +global foo: event(c: string); + +event grault(a: string, b: string &default="G") + { + print "grault", a, b; + } + +event corge(c: string &default="C") + { + print "corge", c; + } + +event foo(c: string &default="CCCC") + { + print "foo c", c; + } + +global bar: function(a: string, b: string); + +function bar(a: string &default="A", b: string &default="B") + { + print "bar", a, b; + } + +global baz: function(a: string &default="A", b: string &default="B"); + +function baz(a: string, b: string) + { + print "baz", a, b; + } + +global qux: function(a: string &default="A", b: string &default="B"); + +function qux(a: string &default="Q", b: string &default="Q") + { + print "qux", a, b; + } + +event zeek_init() + { + bar(); + baz(); + qux(); + event grault("A"); + event corge(); + event foo("A", "B"); + } +