Improve type inference for vector-of-enum constructor

This commit is contained in:
Jon Siwek 2019-07-25 13:49:41 -07:00
parent 9698d8d7cc
commit 70aa886806
5 changed files with 54 additions and 0 deletions

View file

@ -1783,6 +1783,39 @@ BroType* merge_types(const BroType* t1, const BroType* t2)
case TYPE_ERROR: case TYPE_ERROR:
return base_type(tg1); return base_type(tg1);
case TYPE_ENUM:
{
// Could compare pointers t1 == t2, but maybe there's someone out
// there creating clones of the type, so safer to compare name.
if ( t1->GetName() != t2->GetName() )
{
std::string msg = fmt("incompatible enum types: '%s' and '%s'",
t1->GetName().data(), t2->GetName().data());
t1->Error(msg.data(), t2);
return 0;
}
// Doing a lookup here as a roundabout way of ref-ing t1, without
// changing the function params which has t1 as const and also
// (potentially) avoiding a pitfall mentioned earlier about clones.
auto id = global_scope()->Lookup(t1->GetName().data());
if ( id && id->AsType() && id->AsType()->Tag() == TYPE_ENUM )
// It should make most sense to return the real type here rather
// than a copy since it may be redef'd later in parsing. If we
// return a copy, then whoever is using this return value won't
// actually see those changes from the redef.
return id->AsType()->Ref();
std::string msg = fmt("incompatible enum types: '%s' and '%s'"
" ('%s' enum type ID is invalid)",
t1->GetName().data(), t2->GetName().data(),
t1->GetName().data());
t1->Error(msg.data(), t2);
return 0;
}
case TYPE_TABLE: case TYPE_TABLE:
{ {
const IndexType* it1 = (const IndexType*) t1; const IndexType* it1 = (const IndexType*) t1;

View file

@ -0,0 +1,2 @@
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.vector-of-enum-mismatch/vector-of-enum-mismatch.zeek, line 7 and /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.vector-of-enum-mismatch/vector-of-enum-mismatch.zeek, line 8: incompatible enum types: 'color' and 'number' (enum and enum)
error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.vector-of-enum-mismatch/vector-of-enum-mismatch.zeek, line 9: inconsistent types in list

View file

@ -0,0 +1 @@
vector of enum, [Red, Green, Blue]

View file

@ -0,0 +1,9 @@
# @TEST-EXEC-FAIL: zeek -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
# Type inference for vector constructor comprised of disparate enum types
# should raise an error message about the types being incompatible.
type color: enum { Red, Green, Blue };
type number: enum { One, Two, Three, Four};
global v = vector(Red, Four, Blue);

View file

@ -0,0 +1,9 @@
# @TEST-EXEC: zeek -b %INPUT >out
# @TEST-EXEC: btest-diff out
# Type inference for vector constructor comprised of enums should work fine
# (previously the internal merge_types code did not handle enums).
type color: enum { Red, Green, Blue };
global v = vector(Red, Green, Blue);
print type_name(v), v;