Expr: Handle TYPE_VOID in SizeExpr and AssignExpr::Typecheck()

@vpax reported surprising behavior when working with "void values".
While these are not exposed to script land, plumb the places he
pointed out are causing confusing behavior.

Closes #3640.
This commit is contained in:
Arne Welzel 2024-03-07 11:17:24 +01:00
parent eeeaffb42c
commit 8cb1a1518f
9 changed files with 68 additions and 2 deletions

View file

@ -1313,7 +1313,9 @@ SizeExpr::SizeExpr(ExprPtr arg_op) : UnaryExpr(EXPR_SIZE, std::move(arg_op)) {
auto& t = op->GetType();
if ( t->Tag() == TYPE_ANY )
if ( t->Tag() == TYPE_VOID )
SetError("cannot take size of void");
else if ( t->Tag() == TYPE_ANY )
SetType(base_type(TYPE_ANY));
else if ( t->Tag() == TYPE_FILE || t->Tag() == TYPE_SUBNET || t->InternalType() == TYPE_INTERNAL_DOUBLE )
SetType(base_type(TYPE_DOUBLE));
@ -2204,6 +2206,11 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) {
TypeTag bt1 = op1->GetType()->Tag();
TypeTag bt2 = op2->GetType()->Tag();
if ( bt2 == TYPE_VOID ) {
ExprError("can't assign void value");
return false;
}
if ( bt1 == TYPE_LIST && bt2 == TYPE_ANY )
// This is ok because we cannot explicitly declare lists on
// the script level.
@ -2241,7 +2248,7 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) {
}
}
if ( op1->GetType()->Tag() == TYPE_RECORD && op2->GetType()->Tag() == TYPE_RECORD ) {
if ( bt1 == TYPE_RECORD && bt2 == TYPE_RECORD ) {
if ( same_type(op1->GetType(), op2->GetType()) )
return true;