mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 01:28: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
57
src/Val.cc
57
src/Val.cc
|
@ -564,6 +564,35 @@ void Val::ValDescribeReST(ODesc* d) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool Val::WouldOverflow(const BroType* from_type, const BroType* to_type, const Val* val)
|
||||
{
|
||||
if ( !to_type || !from_type )
|
||||
return true;
|
||||
else if ( same_type(to_type, from_type) )
|
||||
return false;
|
||||
|
||||
if ( to_type->InternalType() == TYPE_INTERNAL_DOUBLE )
|
||||
return false;
|
||||
else if ( to_type->InternalType() == TYPE_INTERNAL_UNSIGNED )
|
||||
{
|
||||
if ( from_type->InternalType() == TYPE_INTERNAL_DOUBLE )
|
||||
return (val->InternalDouble() < 0.0 || val->InternalDouble() > static_cast<double>(UINT64_MAX));
|
||||
else if ( from_type->InternalType() == TYPE_INTERNAL_INT )
|
||||
return (val->InternalInt() < 0);
|
||||
}
|
||||
else if ( to_type->InternalType() == TYPE_INTERNAL_INT )
|
||||
{
|
||||
if ( from_type->InternalType() == TYPE_INTERNAL_DOUBLE )
|
||||
return (val->InternalDouble() < static_cast<double>(INT64_MIN) ||
|
||||
val->InternalDouble() > static_cast<double>(INT64_MAX));
|
||||
else if ( from_type->InternalType() == TYPE_INTERNAL_UNSIGNED )
|
||||
return (val->InternalUnsigned() > INT64_MAX);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MutableVal::~MutableVal()
|
||||
{
|
||||
for ( list<ID*>::iterator i = aliases.begin(); i != aliases.end(); ++i )
|
||||
|
@ -3565,7 +3594,7 @@ bool OpaqueVal::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
||||
Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* expr_location)
|
||||
{
|
||||
if ( ! v )
|
||||
return 0;
|
||||
|
@ -3589,7 +3618,7 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
|||
if ( same_type(t, vt, is_init) )
|
||||
return v;
|
||||
|
||||
t->Error("type clash", v);
|
||||
t->Error("type clash", v, 0, expr_location);
|
||||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3598,9 +3627,9 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
|||
(! IsArithmetic(v_tag) || t_tag != TYPE_TIME || ! v->IsZero()) )
|
||||
{
|
||||
if ( t_tag == TYPE_LIST || v_tag == TYPE_LIST )
|
||||
t->Error("list mixed with scalar", v);
|
||||
t->Error("list mixed with scalar", v, 0, expr_location);
|
||||
else
|
||||
t->Error("arithmetic mixed with non-arithmetic", v);
|
||||
t->Error("arithmetic mixed with non-arithmetic", v, 0, expr_location);
|
||||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3608,12 +3637,12 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
|||
if ( v_tag == t_tag )
|
||||
return v;
|
||||
|
||||
if ( t_tag != TYPE_TIME )
|
||||
if ( t_tag != TYPE_TIME && ! BothArithmetic(t_tag, v_tag) )
|
||||
{
|
||||
TypeTag mt = max_type(t_tag, v_tag);
|
||||
if ( mt != t_tag )
|
||||
{
|
||||
t->Error("over-promotion of arithmetic value", v);
|
||||
t->Error("over-promotion of arithmetic value", v, 0, expr_location);
|
||||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3630,7 +3659,13 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
|||
Val* promoted_v;
|
||||
switch ( it ) {
|
||||
case TYPE_INTERNAL_INT:
|
||||
if ( t_tag == TYPE_INT )
|
||||
if ( ( vit == TYPE_INTERNAL_UNSIGNED || vit == TYPE_INTERNAL_DOUBLE ) && Val::WouldOverflow(vt, t, v) )
|
||||
{
|
||||
t->Error("overflow promoting from unsigned/double to signed arithmetic value", v, 0, expr_location);
|
||||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
else if ( t_tag == TYPE_INT )
|
||||
promoted_v = val_mgr->GetInt(v->CoerceToInt());
|
||||
else if ( t_tag == TYPE_BOOL )
|
||||
promoted_v = val_mgr->GetBool(v->CoerceToInt());
|
||||
|
@ -3644,7 +3679,13 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
|||
break;
|
||||
|
||||
case TYPE_INTERNAL_UNSIGNED:
|
||||
if ( t_tag == TYPE_COUNT || t_tag == TYPE_COUNTER )
|
||||
if ( ( vit == TYPE_INTERNAL_DOUBLE || vit == TYPE_INTERNAL_INT) && Val::WouldOverflow(vt, t, v) )
|
||||
{
|
||||
t->Error("overflow promoting from signed/double to unsigned arithmetic value", v, 0, expr_location);
|
||||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
else if ( t_tag == TYPE_COUNT || t_tag == TYPE_COUNTER )
|
||||
promoted_v = val_mgr->GetCount(v->CoerceToUnsigned());
|
||||
else // port
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue