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");
|
ExprError("bad coercion value");
|
||||||
}
|
}
|
||||||
|
|
||||||
ValPtr ArithCoerceExpr::FoldSingleVal(Val* v, InternalTypeTag t) const
|
ValPtr ArithCoerceExpr::FoldSingleVal(ValPtr v, const TypePtr& t) const
|
||||||
{
|
{
|
||||||
switch ( t ) {
|
return check_and_promote(v, t.get(), false, location);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ValPtr ArithCoerceExpr::Fold(Val* v) const
|
ValPtr ArithCoerceExpr::Fold(Val* v) const
|
||||||
{
|
{
|
||||||
InternalTypeTag t = type->InternalType();
|
auto t = GetType();
|
||||||
|
|
||||||
if ( ! is_vector(v) )
|
if ( ! is_vector(v) )
|
||||||
{
|
{
|
||||||
// Our result type might be vector, in which case this
|
// Our result type might be vector, in which case this
|
||||||
// invocation is being done per-element rather than on
|
// 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 )
|
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();
|
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 )
|
for ( unsigned int i = 0; i < vv->Size(); ++i )
|
||||||
{
|
{
|
||||||
auto elt = vv->ValAt(i);
|
auto elt = vv->ValAt(i);
|
||||||
if ( elt )
|
if ( elt )
|
||||||
result->Assign(i, FoldSingleVal(elt.get(), t));
|
result->Assign(i, FoldSingleVal(elt, yt));
|
||||||
else
|
else
|
||||||
result->Assign(i, nullptr);
|
result->Assign(i, nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1213,7 +1213,7 @@ public:
|
||||||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValPtr FoldSingleVal(Val* v, InternalTypeTag t) const;
|
ValPtr FoldSingleVal(ValPtr v, const TypePtr& t) const;
|
||||||
ValPtr Fold(Val* v) const override;
|
ValPtr Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2075,8 +2075,13 @@ ExprPtr ArithCoerceExpr::Duplicate()
|
||||||
|
|
||||||
bool ArithCoerceExpr::WillTransform(Reducer* c) const
|
bool ArithCoerceExpr::WillTransform(Reducer* c) const
|
||||||
{
|
{
|
||||||
return op->Tag() == EXPR_CONST &&
|
if ( op->Tag() != EXPR_CONST )
|
||||||
IsArithmetic(op->AsConstExpr()->Value()->GetType()->Tag());
|
return false;
|
||||||
|
|
||||||
|
if ( IsArithmetic(GetType()->Tag()) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return IsArithmetic(op->AsConstExpr()->Value()->GetType()->Tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprPtr ArithCoerceExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
|
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 )
|
if ( op->Tag() == EXPR_CONST )
|
||||||
{
|
{
|
||||||
auto cv = op->AsConstExpr()->Value();
|
const auto& t = GetType();
|
||||||
auto tag = cv->GetType()->Tag();
|
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));
|
return make_intrusive<ConstExpr>(FoldSingleVal(cv, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue