diff --git a/src/Expr.cc b/src/Expr.cc index d2dcb1585b..049c0981dd 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2599,6 +2599,39 @@ bool AssignExpr::TypeCheck(attr_list* attrs) if ( ! same_type(op1->Type(), op2->Type()) ) { + if ( bt1 == TYPE_TABLE && bt2 == TYPE_TABLE ) + { + if ( op2->Tag() == EXPR_SET_CONSTRUCTOR ) + { + // Some elements in constructor list must not match, see if + // we can create a new constructor now that the expected type + // of LHS is known and let it do coercions where possible. + SetConstructorExpr* sce = dynamic_cast(op2); + ListExpr* ctor_list = dynamic_cast(sce->Op()); + attr_list* attr_copy = 0; + + if ( sce->Attrs() ) + { + attr_list* a = sce->Attrs()->Attrs(); + attrs = new attr_list; + loop_over_list(*a, i) + attrs->append((*a)[i]); + } + + int errors_before = reporter->Errors(); + op2 = new SetConstructorExpr(ctor_list, attr_copy, op1->Type()); + int errors_after = reporter->Errors(); + + if ( errors_after > errors_before ) + { + ExprError("type clash in assignment"); + return false; + } + + return true; + } + } + ExprError("type clash in assignment"); return false; } diff --git a/testing/btest/Baseline/language.set-type-checking/out b/testing/btest/Baseline/language.set-type-checking/out index d93db19abd..707363e9c8 100644 --- a/testing/btest/Baseline/language.set-type-checking/out +++ b/testing/btest/Baseline/language.set-type-checking/out @@ -18,4 +18,7 @@ error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-che error in port and /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 38: arithmetic mixed with non-arithmetic (port and 1002) error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 38 and port: type mismatch (1002 and port) error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 38: inconsistent type in set constructor (set(1002)) +error in port and /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 44: arithmetic mixed with non-arithmetic (port and 1003) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 44 and port: type mismatch (1003 and port) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 44: inconsistent type in set constructor (set(1003)) error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.set-type-checking/set-type-checking.bro, line 44: type clash in assignment (lea = set(1003)) diff --git a/testing/btest/language/set-type-checking.bro b/testing/btest/language/set-type-checking.bro index bf774fb9f9..3c82a29730 100644 --- a/testing/btest/language/set-type-checking.bro +++ b/testing/btest/language/set-type-checking.bro @@ -43,3 +43,18 @@ event bro_init() { local lea: MySet = set(1003); # type clash } + +type MyRecord: record { + user: string; + host: string; + host_port: count &default=22; + path: string; +}; + +global set_of_records: set[MyRecord]; + +event bro_init() + { + # Set ctor w/ anonymous record ctor should coerce. + set_of_records = set([$user="testuser", $host="testhost", $path="testpath"]); + }