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:
Jon Siwek 2019-06-04 17:53:10 -07:00
commit 43104565a4
15 changed files with 305 additions and 35 deletions

View file

@ -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
{