diff --git a/src/Type.h b/src/Type.h index b967524be4..e006627f90 100644 --- a/src/Type.h +++ b/src/Type.h @@ -1024,7 +1024,7 @@ inline bool IsString(TypeTag t) return (t == TYPE_STRING); } -// True if the given type is a container aggregate. +// True if the given type is an aggregate. inline bool IsAggr(TypeTag tag) { return tag == TYPE_VECTOR || tag == TYPE_TABLE || tag == TYPE_RECORD; @@ -1038,6 +1038,12 @@ inline bool IsAggr(const TypePtr& t) return IsAggr(t->Tag()); } +// True if the given type is a container. +inline bool IsContainer(TypeTag tag) + { + return tag == TYPE_VECTOR || tag == TYPE_TABLE; + } + // True if the given type tag corresponds to the error type. inline bool IsErrorType(TypeTag t) { diff --git a/src/Var.cc b/src/Var.cc index a21abb2e73..0686363121 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -381,7 +381,7 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, if ( dt == VAR_OPTION ) { - if ( ! init ) + if ( ! init && ! IsContainer(t->Tag()) ) id->Error("option variable must be initialized"); id->SetOption(); diff --git a/testing/btest/Baseline/language.container-option-init/out b/testing/btest/Baseline/language.container-option-init/out new file mode 100644 index 0000000000..bcb5908cea --- /dev/null +++ b/testing/btest/Baseline/language.container-option-init/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +0 +0 +0 diff --git a/testing/btest/Baseline/language.record-option-init/out b/testing/btest/Baseline/language.record-option-init/out new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/language.record-option-init/out @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/language/container-option-init.zeek b/testing/btest/language/container-option-init.zeek new file mode 100644 index 0000000000..7f8590f684 --- /dev/null +++ b/testing/btest/language/container-option-init.zeek @@ -0,0 +1,14 @@ +# Ensures that an error doesn't print out for option variables +# that are containers. These get automatically initialized so +# there's no need to manually initialize them. + +# @TEST-EXEC: zeek -b %INPUT > out +# @TEST-EXEC: btest-diff out + +option foo: set[count] &redef; +option foo2: table[count] of count &redef; +option foo3: vector of count &redef; + +print |foo|; +print |foo2|; +print |foo3|; \ No newline at end of file diff --git a/testing/btest/language/record-option-init.zeek b/testing/btest/language/record-option-init.zeek new file mode 100644 index 0000000000..b633c7a5d5 --- /dev/null +++ b/testing/btest/language/record-option-init.zeek @@ -0,0 +1,19 @@ +# Ensures that an error is printed out for option variables +# that are containers if they aren't initialized. + +# @TEST-EXEC-FAIL: zeek -b %INPUT > out +# @TEST-EXEC: btest-diff out + +@load misc/stats + +type TestRecord: record { + a: count; + b: Stats::Info &optional; +}; + +option foo: TestRecord &redef; + +event zeek_init() + { + print foo; + }