mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
type-checking for use of empty table constructors in expressions
This commit is contained in:
parent
4d2115ffd3
commit
e786ba2fa9
2 changed files with 35 additions and 16 deletions
49
src/Expr.cc
49
src/Expr.cc
|
@ -2682,21 +2682,11 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs)
|
||||||
// Some elements in constructor list must not match, see if
|
// Some elements in constructor list must not match, see if
|
||||||
// we can create a new constructor now that the expected type
|
// we can create a new constructor now that the expected type
|
||||||
// of LHS is known and let it do coercions where possible.
|
// of LHS is known and let it do coercions where possible.
|
||||||
SetConstructorExpr* sce = dynamic_cast<SetConstructorExpr*>(op2.get());
|
auto sce = cast_intrusive<SetConstructorExpr>(op2);
|
||||||
|
|
||||||
if ( ! sce )
|
|
||||||
{
|
|
||||||
ExprError("Failed typecast to SetConstructorExpr");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ctor_list = cast_intrusive<ListExpr>(sce->GetOp1());
|
auto ctor_list = cast_intrusive<ListExpr>(sce->GetOp1());
|
||||||
|
|
||||||
if ( ! ctor_list )
|
if ( ! ctor_list )
|
||||||
{
|
Internal("failed typecast to ListExpr");
|
||||||
ExprError("Failed typecast to ListExpr");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<std::vector<AttrPtr>> attr_copy;
|
std::unique_ptr<std::vector<AttrPtr>> attr_copy;
|
||||||
|
|
||||||
|
@ -4226,13 +4216,23 @@ RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector<int>&
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableCoerceExpr::TableCoerceExpr(ExprPtr arg_op, TableTypePtr r)
|
TableCoerceExpr::TableCoerceExpr(ExprPtr arg_op, TableTypePtr tt, bool type_check)
|
||||||
: UnaryExpr(EXPR_TABLE_COERCE, std::move(arg_op))
|
: UnaryExpr(EXPR_TABLE_COERCE, std::move(arg_op))
|
||||||
{
|
{
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetType(std::move(r));
|
if ( type_check )
|
||||||
|
{
|
||||||
|
op = check_and_promote_expr(op, tt);
|
||||||
|
if ( ! op )
|
||||||
|
{
|
||||||
|
SetError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetType(std::move(tt));
|
||||||
|
|
||||||
if ( GetType()->Tag() != TYPE_TABLE )
|
if ( GetType()->Tag() != TYPE_TABLE )
|
||||||
ExprError("coercion to non-table");
|
ExprError("coercion to non-table");
|
||||||
|
@ -5260,7 +5260,26 @@ ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t)
|
||||||
{
|
{
|
||||||
if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE &&
|
if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE &&
|
||||||
et->AsTableType()->IsUnspecifiedTable() )
|
et->AsTableType()->IsUnspecifiedTable() )
|
||||||
return make_intrusive<TableCoerceExpr>(e, IntrusivePtr{NewRef{}, t->AsTableType()});
|
{
|
||||||
|
if ( e->Tag() == EXPR_TABLE_CONSTRUCTOR )
|
||||||
|
{
|
||||||
|
auto& attrs = cast_intrusive<TableConstructorExpr>(e)->GetAttrs();
|
||||||
|
auto& def = attrs ? attrs->Find(ATTR_DEFAULT) : nullptr;
|
||||||
|
if ( def )
|
||||||
|
{
|
||||||
|
std::string err_msg;
|
||||||
|
if ( ! check_default_attr(def.get(), t, false, false, err_msg) )
|
||||||
|
{
|
||||||
|
if ( ! err_msg.empty() )
|
||||||
|
t->Error(err_msg.c_str(), e.get());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_intrusive<TableCoerceExpr>(e, IntrusivePtr{NewRef{}, t->AsTableType()},
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR &&
|
if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR &&
|
||||||
et->AsVectorType()->IsUnspecifiedVector() )
|
et->AsVectorType()->IsUnspecifiedVector() )
|
||||||
|
|
|
@ -1310,7 +1310,7 @@ extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector
|
||||||
class TableCoerceExpr final : public UnaryExpr
|
class TableCoerceExpr final : public UnaryExpr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TableCoerceExpr(ExprPtr op, TableTypePtr r);
|
TableCoerceExpr(ExprPtr op, TableTypePtr r, bool type_check = true);
|
||||||
~TableCoerceExpr() override;
|
~TableCoerceExpr() override;
|
||||||
|
|
||||||
// Optimization-related:
|
// Optimization-related:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue