diff --git a/CHANGES b/CHANGES index 804bc3642b..26fd059492 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +2.3-305 | 2014-11-18 11:09:04 -0800 + + * Improve coercion of &default expressions. Addresses BIT-1288. (Jon + Siwek) + 2.3-303 | 2014-11-18 10:53:04 -0800 * For DH key exchanges, use p as the parameter for weak key diff --git a/VERSION b/VERSION index 249fe33eb6..fd48b52d6d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3-303 +2.3-305 diff --git a/src/Attr.cc b/src/Attr.cc index d6d0f6e68d..13106b02b7 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -265,6 +265,14 @@ void Attributes::CheckAttr(Attr* a) // Ok. 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); } @@ -297,8 +305,11 @@ void Attributes::CheckAttr(Attr* a) Expr* e = a->AttrExpr(); if ( check_and_promote_expr(e, ytype) ) + { + a->SetAttrExpr(e); // Ok. break; + } Error("&default value has inconsistent type 2"); } diff --git a/src/Attr.h b/src/Attr.h index 7becbb27eb..228bc2e5fc 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -45,6 +45,13 @@ public: attr_tag Tag() const { return tag; } 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 { return tag == ATTR_REDEF || tag == ATTR_OPTIONAL; } diff --git a/testing/btest/Baseline/language.attr-default-coercion/out b/testing/btest/Baseline/language.attr-default-coercion/out new file mode 100644 index 0000000000..e6768c77b6 --- /dev/null +++ b/testing/btest/Baseline/language.attr-default-coercion/out @@ -0,0 +1,5 @@ +7.0 +[i=1, d=3.0] +237, 101.0 +-5, 101.0 +-37, -8.1 diff --git a/testing/btest/Baseline/language.named-table-ctors/out b/testing/btest/Baseline/language.named-table-ctors/out index 273afdd205..5a305f4d4b 100644 --- a/testing/btest/Baseline/language.named-table-ctors/out +++ b/testing/btest/Baseline/language.named-table-ctors/out @@ -16,7 +16,7 @@ [one] = 1.0, [three] = 3.0 } -0 +0.0 { [42] = forty-two, [37] = thirty-seven diff --git a/testing/btest/language/attr-default-coercion.bro b/testing/btest/language/attr-default-coercion.bro new file mode 100644 index 0000000000..14590d0033 --- /dev/null +++ b/testing/btest/language/attr-default-coercion.bro @@ -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); + }