fixes for constructing and assigning records with fields that are empty vectors

This commit is contained in:
Vern Paxson 2021-11-16 12:11:30 -08:00
parent bdb5222c27
commit 06bbd167cd
6 changed files with 37 additions and 5 deletions

View file

@ -3405,12 +3405,21 @@ ValPtr RecordConstructorExpr::Eval(Frame* f) const
if ( ! map && exprs.length() != rt->NumFields() )
RuntimeErrorWithCallStack("inconsistency evaluating record constructor");
auto rv = make_intrusive<RecordVal>(std::move(rt));
auto rv = make_intrusive<RecordVal>(rt);
for ( int i = 0; i < exprs.length(); ++i )
{
auto v_i = exprs[i]->Eval(f);
int ind = map ? (*map)[i] : i;
rv->Assign(ind, exprs[i]->Eval(f));
if ( v_i && v_i->GetType()->Tag() == TYPE_VECTOR &&
v_i->GetType<VectorType>()->IsUnspecifiedVector() )
{
const auto& t_ind = rt->GetFieldType(ind);
v_i->AsVectorVal()->Concretize(t_ind->Yield());
}
rv->Assign(ind, v_i);
}
return rv;
@ -4105,6 +4114,13 @@ RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector<int>&
cast_intrusive<RecordType>(field_type)) )
rhs = std::move(new_val);
}
else if ( rhs_type->Tag() == TYPE_VECTOR && field_type->Tag() == TYPE_VECTOR &&
rhs_type->AsVectorType()->IsUnspecifiedVector() )
{
auto rhs_v = rhs->AsVectorVal();
if ( ! rhs_v->Concretize(field_type->Yield()) )
reporter->InternalError("could not concretize empty vector");
}
else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) &&
! same_type(rhs_type, field_type) )
{
@ -5049,7 +5065,7 @@ ValPtr ListExpr::InitVal(const zeek::Type* t, ValPtr aggr) const
ValPtr ListExpr::AddSetInit(const zeek::Type* t, ValPtr aggr) const
{
if ( aggr->GetType()->Tag() != TYPE_TABLE )
Internal("bad aggregate in ListExpr::InitVal");
Internal("bad aggregate in ListExpr::AddSetInit");
TableVal* tv = aggr->AsTableVal();
const TableType* tt = tv->GetType()->AsTableType();

View file

@ -3646,6 +3646,7 @@ bool VectorVal::Concretize(const TypePtr& t)
}
// Require that this vector be treated consistently in the future.
type = make_intrusive<VectorType>(t);
yield_type = t;
managed_yield = ZVal::IsManagedType(yield_type);
delete yield_types;

View file

@ -1,3 +1,3 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in <...>/record-ceorce-orphan.zeek, line 19: orphaned field "wtf" in record coercion ((coerce [$a=test, $b=42, $wtf=1.0 sec] to myrec))
error in <...>/record-ceorce-orphan.zeek, line 21: orphaned field "wtf" in record coercion ((coerce [$a=test, $b=42, $wtf=1.0 sec] to myrec))
error in <...>/record-coerce-orphan.zeek, line 19: orphaned field "wtf" in record coercion ((coerce [$a=test, $b=42, $wtf=1.0 sec] to myrec))
error in <...>/record-coerce-orphan.zeek, line 21: orphaned field "wtf" in record coercion ((coerce [$a=test, $b=42, $wtf=1.0 sec] to myrec))

View file

@ -0,0 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
[, 9]

View file

@ -0,0 +1,13 @@
# @TEST-EXEC: zeek -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
type r: record {
v: vector of int;
};
event zeek_init()
{
local l = r($v=vector());
l$v[1] = 9;
print l$v;
}