mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 12:08:20 +00:00
Merge remote-tracking branch 'origin/topic/timw/159-coerce-counts'
* origin/topic/timw/159-coerce-counts: GHI-155: set the type of a vector based on the variable's type, not the value's type GH-159: Allow coercion of numeric values into other types Allow passing a location to BroObj::Warning and BroObj::Error. Add CLion directories to gitignore Move #define outside of max_type for clarity
This commit is contained in:
commit
43104565a4
15 changed files with 305 additions and 35 deletions
64
src/Expr.cc
64
src/Expr.cc
|
@ -2591,7 +2591,7 @@ bool AssignExpr::TypeCheck(attr_list* attrs)
|
|||
|
||||
if ( op2->Tag() == EXPR_LIST )
|
||||
{
|
||||
op2 = new VectorConstructorExpr(op2->AsListExpr());
|
||||
op2 = new VectorConstructorExpr(op2->AsListExpr(), op1->Type());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4136,15 +4136,41 @@ RecordCoerceExpr::RecordCoerceExpr(Expr* op, RecordType* r)
|
|||
|
||||
if ( ! same_type(sup_t_i, sub_t_i) )
|
||||
{
|
||||
if ( sup_t_i->Tag() != TYPE_RECORD ||
|
||||
sub_t_i->Tag() != TYPE_RECORD ||
|
||||
! record_promotion_compatible(sup_t_i->AsRecordType(),
|
||||
sub_t_i->AsRecordType()) )
|
||||
auto is_arithmetic_promotable = [](BroType* sup, BroType* sub) -> bool
|
||||
{
|
||||
char buf[512];
|
||||
safe_snprintf(buf, sizeof(buf),
|
||||
auto sup_tag = sup->Tag();
|
||||
auto sub_tag = sub->Tag();
|
||||
|
||||
if ( ! BothArithmetic(sup_tag, sub_tag) )
|
||||
return false;
|
||||
|
||||
if ( sub_tag == TYPE_DOUBLE && IsIntegral(sup_tag) )
|
||||
return false;
|
||||
|
||||
if ( sub_tag == TYPE_INT && sup_tag == TYPE_COUNT )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto is_record_promotable = [](BroType* sup, BroType* sub) -> bool
|
||||
{
|
||||
if ( sup->Tag() != TYPE_RECORD )
|
||||
return false;
|
||||
|
||||
if ( sub->Tag() != TYPE_RECORD )
|
||||
return false;
|
||||
|
||||
return record_promotion_compatible(sup->AsRecordType(),
|
||||
sub->AsRecordType());
|
||||
};
|
||||
|
||||
if ( ! is_arithmetic_promotable(sup_t_i, sub_t_i) &&
|
||||
! is_record_promotable(sup_t_i, sub_t_i) )
|
||||
{
|
||||
string error_msg = fmt(
|
||||
"type clash for field \"%s\"", sub_r->FieldName(i));
|
||||
Error(buf, sub_t_i);
|
||||
Error(error_msg.c_str(), sub_t_i);
|
||||
SetError();
|
||||
break;
|
||||
}
|
||||
|
@ -4162,11 +4188,9 @@ RecordCoerceExpr::RecordCoerceExpr(Expr* op, RecordType* r)
|
|||
{
|
||||
if ( ! t_r->FieldDecl(i)->FindAttr(ATTR_OPTIONAL) )
|
||||
{
|
||||
char buf[512];
|
||||
safe_snprintf(buf, sizeof(buf),
|
||||
"non-optional field \"%s\" missing",
|
||||
t_r->FieldName(i));
|
||||
Error(buf);
|
||||
string error_msg = fmt(
|
||||
"non-optional field \"%s\" missing", t_r->FieldName(i));
|
||||
Error(error_msg.c_str());
|
||||
SetError();
|
||||
break;
|
||||
}
|
||||
|
@ -4254,6 +4278,20 @@ Val* RecordCoerceExpr::Fold(Val* v) const
|
|||
rhs = new_val;
|
||||
}
|
||||
}
|
||||
else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) &&
|
||||
! same_type(rhs_type, field_type) )
|
||||
{
|
||||
if ( Val* new_val = check_and_promote(rhs, field_type, false, op->GetLocationInfo()) )
|
||||
{
|
||||
// Don't call unref here on rhs because check_and_promote already called it.
|
||||
rhs = new_val;
|
||||
}
|
||||
else
|
||||
{
|
||||
Unref(val);
|
||||
RuntimeError("Failed type conversion");
|
||||
}
|
||||
}
|
||||
|
||||
val->Assign(i, rhs);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue