GH-1122: Improve error for global record initialization exceptions

This commit is contained in:
Jon Siwek 2020-08-26 14:24:36 -07:00
parent ff0aa6b050
commit cf06ade325
4 changed files with 41 additions and 2 deletions

View file

@ -2886,7 +2886,22 @@ RecordVal::RecordVal(RecordTypePtr t, bool init_fields) : Val(std::move(t))
{ {
detail::Attributes* a = rt->FieldDecl(i)->attrs.get(); detail::Attributes* a = rt->FieldDecl(i)->attrs.get();
detail::Attr* def_attr = a ? a->Find(detail::ATTR_DEFAULT).get() : nullptr; detail::Attr* def_attr = a ? a->Find(detail::ATTR_DEFAULT).get() : nullptr;
auto def = def_attr ? def_attr->GetExpr()->Eval(nullptr) : nullptr; ValPtr def;
if ( def_attr )
try
{
def = def_attr->GetExpr()->Eval(nullptr);
}
catch ( InterpreterException& )
{
if ( run_state::is_parsing )
parse_time_records[rt].pop_back();
delete AsNonConstRecord();
throw;
}
const auto& type = rt->FieldDecl(i)->type; const auto& type = rt->FieldDecl(i)->type;
if ( def && type->Tag() == TYPE_RECORD && if ( def && type->Tag() == TYPE_RECORD &&

View file

@ -251,8 +251,16 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
ValPtr aggr; ValPtr aggr;
if ( t->Tag() == TYPE_RECORD ) if ( t->Tag() == TYPE_RECORD )
{
try
{ {
aggr = make_intrusive<RecordVal>(cast_intrusive<RecordType>(t)); aggr = make_intrusive<RecordVal>(cast_intrusive<RecordType>(t));
}
catch ( InterpreterException& )
{
id->Error("initialization failed");
return;
}
if ( init && t ) if ( init && t )
// Have an initialization and type is not deduced. // Have an initialization and type is not deduced.

View file

@ -0,0 +1,2 @@
expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.record-global-init-exception/record-global-init-exception.zeek, line 7: value used but not set (my_count)
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.record-global-init-exception/record-global-init-exception.zeek, line 14: initialization failed (my_record)

View file

@ -0,0 +1,14 @@
# @TEST-EXEC-FAIL: zeek -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
global my_count: count;
type MyRecord: record {
f: count &default=my_count;
};
# This global initialization encounters the uninitialized 'my_count' when
# evaluating the &default expression. The test simply checking that the
# interpreter exception is caught and at least fails out with a nice error
# message instead of letting an uncaught exception cause termination.
global my_record = MyRecord();