Add warning for ineffective &default arguments in handlers

For event/hook handlers that had a previous declaration, any &default
arguments are ineffective.  Only &default uses in the initial
prototype's arguments have an effect (that includes if the handler
is actually the site at which the declaration occurs).
This commit is contained in:
Jon Siwek 2020-04-09 22:34:34 -07:00
parent 9243341e8c
commit 640dbea57c
6 changed files with 99 additions and 13 deletions

2
doc

@ -1 +1 @@
Subproject commit 9e77250acc4b5eaf03c0535e8ea00a0a4d19cae0
Subproject commit d8ddfa04683d6b062cbb22b1198163748a45aade

View file

@ -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);
}

View file

@ -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;

View file

@ -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()) )

View file

@ -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

View file

@ -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");
}