BIT-1288: Improve coercion of &default expressions.

This commit is contained in:
Jon Siwek 2014-11-18 12:40:16 -06:00
parent 08d843c258
commit f214158cc5
5 changed files with 50 additions and 1 deletions

View file

@ -265,6 +265,14 @@ void Attributes::CheckAttr(Attr* a)
// Ok. // Ok.
break; break;
Expr* e = a->AttrExpr();
if ( check_and_promote_expr(e, type) )
{
a->SetAttrExpr(e);
// Ok.
break;
}
a->AttrExpr()->Error("&default value has inconsistent type", type); a->AttrExpr()->Error("&default value has inconsistent type", type);
} }
@ -297,8 +305,11 @@ void Attributes::CheckAttr(Attr* a)
Expr* e = a->AttrExpr(); Expr* e = a->AttrExpr();
if ( check_and_promote_expr(e, ytype) ) if ( check_and_promote_expr(e, ytype) )
{
a->SetAttrExpr(e);
// Ok. // Ok.
break; break;
}
Error("&default value has inconsistent type 2"); Error("&default value has inconsistent type 2");
} }

View file

@ -45,6 +45,13 @@ public:
attr_tag Tag() const { return tag; } attr_tag Tag() const { return tag; }
Expr* AttrExpr() const { return expr; } Expr* AttrExpr() const { return expr; }
// Up to the caller to decide if previous expr can be unref'd since it may
// not always be safe. e.g. expressions (at time of writing) don't always
// keep careful track of referencing their operands, so doing something
// like SetAttrExpr(coerce(AttrExpr())) must not completely unref the
// previous expr as the new expr depends on it.
void SetAttrExpr(Expr* e) { expr = e; }
int RedundantAttrOkay() const int RedundantAttrOkay() const
{ return tag == ATTR_REDEF || tag == ATTR_OPTIONAL; } { return tag == ATTR_REDEF || tag == ATTR_OPTIONAL; }

View file

@ -0,0 +1,5 @@
7.0
[i=1, d=3.0]
237, 101.0
-5, 101.0
-37, -8.1

View file

@ -16,7 +16,7 @@
[one] = 1.0, [one] = 1.0,
[three] = 3.0 [three] = 3.0
} }
0 0.0
{ {
[42] = forty-two, [42] = forty-two,
[37] = thirty-seven [37] = thirty-seven

View file

@ -0,0 +1,26 @@
# @TEST-EXEC: bro -b %INPUT >out
# @TEST-EXEC: btest-diff out
type my_table: table[string] of double;
type my_record: record {
i: int &default = 1;
d: double &default = 3;
};
global t: my_table &default = 7;
global r = my_record();
function foo(i: int &default = 237, d: double &default = 101)
{
print i, d;
}
event bro_init()
{
print t["nope"];
print r;
foo();
foo(-5);
foo(-37, -8.1);
}