mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
more robust treatment of arithmetic coercions
This commit is contained in:
parent
e06d988bfd
commit
292bd1b671
3 changed files with 22 additions and 29 deletions
33
src/Expr.cc
33
src/Expr.cc
|
@ -3844,49 +3844,36 @@ ArithCoerceExpr::ArithCoerceExpr(ExprPtr arg_op, TypeTag t)
|
|||
ExprError("bad coercion value");
|
||||
}
|
||||
|
||||
ValPtr ArithCoerceExpr::FoldSingleVal(Val* v, InternalTypeTag t) const
|
||||
ValPtr ArithCoerceExpr::FoldSingleVal(ValPtr v, const TypePtr& t) const
|
||||
{
|
||||
switch ( t ) {
|
||||
case TYPE_INTERNAL_DOUBLE:
|
||||
return make_intrusive<DoubleVal>(v->CoerceToDouble());
|
||||
|
||||
case TYPE_INTERNAL_INT:
|
||||
return val_mgr->Int(v->CoerceToInt());
|
||||
|
||||
case TYPE_INTERNAL_UNSIGNED:
|
||||
return val_mgr->Count(v->CoerceToUnsigned());
|
||||
|
||||
default:
|
||||
RuntimeErrorWithCallStack("bad type in CoerceExpr::Fold");
|
||||
return nullptr;
|
||||
}
|
||||
return check_and_promote(v, t.get(), false, location);
|
||||
}
|
||||
|
||||
ValPtr ArithCoerceExpr::Fold(Val* v) const
|
||||
{
|
||||
InternalTypeTag t = type->InternalType();
|
||||
auto t = GetType();
|
||||
|
||||
if ( ! is_vector(v) )
|
||||
{
|
||||
// Our result type might be vector, in which case this
|
||||
// invocation is being done per-element rather than on
|
||||
// the whole vector. Correct the type tag if necessary.
|
||||
// the whole vector. Correct the type if so.
|
||||
if ( type->Tag() == TYPE_VECTOR )
|
||||
t = GetType()->AsVectorType()->Yield()->InternalType();
|
||||
t = t->AsVectorType()->Yield();
|
||||
|
||||
return FoldSingleVal(v, t);
|
||||
return FoldSingleVal({NewRef{}, v}, t);
|
||||
}
|
||||
|
||||
t = GetType()->AsVectorType()->Yield()->InternalType();
|
||||
|
||||
VectorVal* vv = v->AsVectorVal();
|
||||
auto result = make_intrusive<VectorVal>(GetType<VectorType>());
|
||||
auto result = make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
|
||||
|
||||
auto yt = t->AsVectorType()->Yield();
|
||||
|
||||
for ( unsigned int i = 0; i < vv->Size(); ++i )
|
||||
{
|
||||
auto elt = vv->ValAt(i);
|
||||
if ( elt )
|
||||
result->Assign(i, FoldSingleVal(elt.get(), t));
|
||||
result->Assign(i, FoldSingleVal(elt, yt));
|
||||
else
|
||||
result->Assign(i, nullptr);
|
||||
}
|
||||
|
|
|
@ -1213,7 +1213,7 @@ public:
|
|||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||
|
||||
protected:
|
||||
ValPtr FoldSingleVal(Val* v, InternalTypeTag t) const;
|
||||
ValPtr FoldSingleVal(ValPtr v, const TypePtr& t) const;
|
||||
ValPtr Fold(Val* v) const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -2075,8 +2075,13 @@ ExprPtr ArithCoerceExpr::Duplicate()
|
|||
|
||||
bool ArithCoerceExpr::WillTransform(Reducer* c) const
|
||||
{
|
||||
return op->Tag() == EXPR_CONST &&
|
||||
IsArithmetic(op->AsConstExpr()->Value()->GetType()->Tag());
|
||||
if ( op->Tag() != EXPR_CONST )
|
||||
return false;
|
||||
|
||||
if ( IsArithmetic(GetType()->Tag()) )
|
||||
return true;
|
||||
|
||||
return IsArithmetic(op->AsConstExpr()->Value()->GetType()->Tag());
|
||||
}
|
||||
|
||||
ExprPtr ArithCoerceExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
|
||||
|
@ -2093,10 +2098,11 @@ ExprPtr ArithCoerceExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
|
|||
|
||||
if ( op->Tag() == EXPR_CONST )
|
||||
{
|
||||
auto cv = op->AsConstExpr()->Value();
|
||||
auto tag = cv->GetType()->Tag();
|
||||
const auto& t = GetType();
|
||||
auto cv = op->AsConstExpr()->ValuePtr();
|
||||
const auto& ct = cv->GetType();
|
||||
|
||||
if ( IsArithmetic(tag) )
|
||||
if ( IsArithmetic(t->Tag()) || IsArithmetic(ct->Tag()) )
|
||||
return make_intrusive<ConstExpr>(FoldSingleVal(cv, t));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue