&expire_func(table, arg1, arg2, ...) + type checking.

This commit is contained in:
Zeke Medley 2019-07-18 12:11:27 -07:00
parent c22edc28a5
commit 0ca6b3e013
5 changed files with 110 additions and 25 deletions

View file

@ -434,24 +434,43 @@ void Attributes::CheckAttr(Attr* a)
Error("expiration only applicable to tables");
break;
}
const Expr* expire_func = a->AttrExpr();
if ( expire_func->Type()->Tag() != TYPE_FUNC )
Error("&expire_func attribute is not a function");
const FuncType* e_ft = expire_func->Type()->AsFuncType();
if ( ((const BroType*) e_ft)->YieldType()->Tag() != TYPE_INTERVAL )
if ( e_ft->YieldType()->Tag() != TYPE_INTERVAL )
{
Error("&expire_func must yield a value of type interval");
break;
}
if ( e_ft->Args()->NumFields() != 2 )
{
Error("&expire_func function must take exactly two arguments");
const TableType* the_table = type->AsTableType();
if (the_table->IsUnspecifiedTable())
break;
const type_list* func_index_types = e_ft->ArgTypes()->Types();
// Keep backwards compatability wth idx: any idiom.
if ( func_index_types->length() == 2 )
{
if ((*func_index_types)[1]->Tag() == TYPE_ANY)
break;
}
// ### Should type-check arguments to make sure first is
// table type and second is table index type.
const type_list* table_index_types = the_table->IndexTypes();
type_list expected_args;
expected_args.push_back(type->AsTableType());
for (const auto& t : *table_index_types)
{
expected_args.push_back(t);
}
if ( ! e_ft->CheckArgs(&expected_args) )
Error("&expire_func argument type clash");
}
break;