Fix record constructors in table initializer indices. Addresses #660.

For an index expression list, ListExpr::InitVal() passed the TypeList
to Expr::InitVal() for each expression element in the list instead of
the type for that element.  This made RecordConstructorExpr::InitVal()
complain since it expects a RecordType and not a TypeList with a
RecordType element as an argument.  In most other cases, Expr::InitVal()
worked because check_and_promote() "flattens" the list to a single type.
This commit is contained in:
Jon Siwek 2012-12-12 14:52:08 -06:00
parent b867333c2e
commit f6d5da423c
8 changed files with 350 additions and 2 deletions

View file

@ -4893,9 +4893,16 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const
{
ListVal* v = new ListVal(TYPE_ANY);
const type_list* tl = type->AsTypeList()->Types();
if ( exprs.length() != tl->length() )
{
Error("index mismatch", t);
return 0;
}
loop_over_list(exprs, i)
{
Val* vi = exprs[i]->InitVal(t, 0);
Val* vi = exprs[i]->InitVal((*tl)[i], 0);
if ( ! vi )
{
Unref(v);

View file

@ -0,0 +1,25 @@
following should all be true...
T
T
T
T
T
T
T
T
1
1
1
following should all be false...
F
F
F
now here's the foo table...
{
[[a=foo, b=2], 2] = 2,
[[a=baz, b=6], 6] = 6,
[[a=bar, b=4], 4] = 4,
[[a=baz, b=5], 5] = 5,
[[a=bar, b=3], 3] = 3,
[[a=foo, b=1], 1] = 1
}

View file

@ -0,0 +1,25 @@
following should all be true...
T
T
T
T
T
T
T
T
1
1
1
following should all be false...
F
F
F
now here's the foo table...
{
[[a=baz, b=5]] = 5,
[[a=foo, b=2]] = 2,
[[a=baz, b=6]] = 6,
[[a=foo, b=1]] = 1,
[[a=bar, b=4]] = 4,
[[a=bar, b=3]] = 3
}

View file

@ -0,0 +1,25 @@
following should all be true...
T
T
T
T
T
T
T
T
1
1
1
following should all be false...
F
F
F
now here's the foo table...
{
[[a=foo, b=2], 2] = 2,
[[a=baz, b=6], 6] = 6,
[[a=bar, b=4], 4] = 4,
[[a=baz, b=5], 5] = 5,
[[a=bar, b=3], 3] = 3,
[[a=foo, b=1], 1] = 1
}

View file

@ -0,0 +1,25 @@
following should all be true...
T
T
T
T
T
T
T
T
1
1
1
following should all be false...
F
F
F
now here's the foo table...
{
[[a=foo, b=2], 2] = 2,
[[a=baz, b=6], 6] = 6,
[[a=bar, b=4], 4] = 4,
[[a=baz, b=5], 5] = 5,
[[a=bar, b=3], 3] = 3,
[[a=foo, b=1], 1] = 1
}

View file

@ -0,0 +1,25 @@
following should all be true...
T
T
T
T
T
T
T
T
1
1
1
following should all be false...
F
F
F
now here's the foo table...
{
[[a=baz, b=5]] = 5,
[[a=foo, b=2]] = 2,
[[a=baz, b=6]] = 6,
[[a=foo, b=1]] = 1,
[[a=bar, b=4]] = 4,
[[a=bar, b=3]] = 3
}

View file

@ -2,7 +2,7 @@
# @TEST-EXEC: btest-diff output
# The various container constructor expressions should work in table
# initialization lists.
# initialization lists (as yields).
type set_yield: set[string, count];
type vector_yield: vector of count;

View file

@ -0,0 +1,216 @@
# @TEST-EXEC: bro -b %INPUT >output
# @TEST-EXEC: btest-diff output
# Record constructors should work in table initializers
type r: record {
a: string;
b: count;
};
global a: r = [$a="foo", $b=1];
global b: r = [$a="foo", $b=2];
global c: r = [$a="bar", $b=3];
global d: r = [$a="bar", $b=4];
global e: r = [$a="baz", $b=5];
global f: r = [$a="baz", $b=6];
global foo: table[r] of count = {
[a] = 1,
[record($a="foo", $b=2)] = 2,
[[$a="bar", $b=3]] = 3,
};
foo[d] = 4;
foo[[$a="baz", $b=5]] = 5;
foo[record($a="baz", $b=6)] = 6;
print "following should all be true...";
print a in foo;
print b in foo;
print c in foo;
print d in foo;
print e in foo;
print f in foo;
print [$a="foo", $b=1] in foo;
print record($a="foo", $b=1) in foo;
print foo[a];
print foo[[$a="foo", $b=1]];
print foo[record($a="foo", $b=1)];
print "following should all be false...";
local bah: r = [$a="bah", $b=0];
print bah in foo;
print [$a="bah", $b=0] in foo;
print record($a="bah", $b=0) in foo;
print "now here's the foo table...";
print foo;
# @TEST-START-NEXT
# They can be part of a compound index type, too...
type r: record {
a: string;
b: count;
};
global a: r = [$a="foo", $b=1];
global b: r = [$a="foo", $b=2];
global c: r = [$a="bar", $b=3];
global d: r = [$a="bar", $b=4];
global e: r = [$a="baz", $b=5];
global f: r = [$a="baz", $b=6];
global foo: table[r, count] of count = {
[a, 1] = 1,
[record($a="foo", $b=2), 2] = 2,
[[$a="bar", $b=3], 3] = 3,
};
foo[d, 4] = 4;
foo[[$a="baz", $b=5], 5] = 5;
foo[record($a="baz", $b=6), 6] = 6;
print "following should all be true...";
print [a, 1] in foo;
print [b, 2] in foo;
print [c, 3] in foo;
print [d, 4] in foo;
print [e, 5] in foo;
print [f, 6] in foo;
print [[$a="foo", $b=1], 1] in foo;
print [record($a="foo", $b=1), 1] in foo;
print foo[a, 1];
print foo[[$a="foo", $b=1], 1];
print foo[record($a="foo", $b=1), 1];
print "following should all be false...";
local bah: r = [$a="bah", $b=0];
print [bah, 0] in foo;
print [[$a="bah", $b=0], 0] in foo;
print [record($a="bah", $b=0), 0] in foo;
print "now here's the foo table...";
print foo;
# @TEST-START-NEXT
# Now checking table() ctor versus { } initializer
type r: record {
a: string;
b: count;
};
global a: r = [$a="foo", $b=1];
global b: r = [$a="foo", $b=2];
global c: r = [$a="bar", $b=3];
global d: r = [$a="bar", $b=4];
global e: r = [$a="baz", $b=5];
global f: r = [$a="baz", $b=6];
global foo: table[r] of count = table(
[a] = 1,
[record($a="foo", $b=2)] = 2,
[[$a="bar", $b=3]] = 3
);
foo[d] = 4;
foo[[$a="baz", $b=5]] = 5;
foo[record($a="baz", $b=6)] = 6;
print "following should all be true...";
print a in foo;
print b in foo;
print c in foo;
print d in foo;
print e in foo;
print f in foo;
print [$a="foo", $b=1] in foo;
print record($a="foo", $b=1) in foo;
print foo[a];
print foo[[$a="foo", $b=1]];
print foo[record($a="foo", $b=1)];
print "following should all be false...";
local bah: r = [$a="bah", $b=0];
print bah in foo;
print [$a="bah", $b=0] in foo;
print record($a="bah", $b=0) in foo;
print "now here's the foo table...";
print foo;
# @TEST-START-NEXT
# Now checking table() ctor versus { } initializer for compound index
type r: record {
a: string;
b: count;
};
global a: r = [$a="foo", $b=1];
global b: r = [$a="foo", $b=2];
global c: r = [$a="bar", $b=3];
global d: r = [$a="bar", $b=4];
global e: r = [$a="baz", $b=5];
global f: r = [$a="baz", $b=6];
global foo: table[r, count] of count = table(
[a, 1] = 1,
[record($a="foo", $b=2), 2] = 2,
[[$a="bar", $b=3], 3] = 3
);
foo[d, 4] = 4;
foo[[$a="baz", $b=5], 5] = 5;
foo[record($a="baz", $b=6), 6] = 6;
print "following should all be true...";
print [a, 1] in foo;
print [b, 2] in foo;
print [c, 3] in foo;
print [d, 4] in foo;
print [e, 5] in foo;
print [f, 6] in foo;
print [[$a="foo", $b=1], 1] in foo;
print [record($a="foo", $b=1), 1] in foo;
print foo[a, 1];
print foo[[$a="foo", $b=1], 1];
print foo[record($a="foo", $b=1), 1];
print "following should all be false...";
local bah: r = [$a="bah", $b=0];
print [bah, 0] in foo;
print [[$a="bah", $b=0], 0] in foo;
print [record($a="bah", $b=0), 0] in foo;
print "now here's the foo table...";
print foo;