From 4e5a56c5e0969977243c413f1edcfbf66cd5b2ed Mon Sep 17 00:00:00 2001 From: Evan Typanski Date: Thu, 14 Aug 2025 09:29:50 -0400 Subject: [PATCH] Only allow `&optional` in records There was some confusing behavior with &optional and locals, so this should get rid of that by making it an error. However, there is a case where function parameters are still allowed to have &optional - this is because there are checks for &default in parameters as well. --- src/Attr.cc | 6 +++--- .../language.attr-default-global-set-error/out | 2 +- .../Baseline/language.invalid-optional-attr/out | 3 +++ testing/btest/language/invalid-optional-attr.zeek | 12 ++++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 testing/btest/Baseline/language.invalid-optional-attr/out create mode 100644 testing/btest/language/invalid-optional-attr.zeek diff --git a/src/Attr.cc b/src/Attr.cc index 52c7c461b6..998d48e9b5 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -297,10 +297,10 @@ bool Attributes::CheckAttr(Attr* a) { case ATTR_IS_USED: break; case ATTR_OPTIONAL: - if ( global_var ) - return AttrError("&optional is not valid for global variables"); + if ( ! in_record ) + return AttrError("&optional is only valid for record fields"); - if ( in_record && Find(ATTR_DEFAULT) ) + if ( Find(ATTR_DEFAULT) ) return AttrError("Using &default and &optional together results in &default behavior"); break; diff --git a/testing/btest/Baseline/language.attr-default-global-set-error/out b/testing/btest/Baseline/language.attr-default-global-set-error/out index 431b2d445b..683c0c0db5 100644 --- a/testing/btest/Baseline/language.attr-default-global-set-error/out +++ b/testing/btest/Baseline/language.attr-default-global-set-error/out @@ -2,5 +2,5 @@ error in <...>/attr-default-global-set-error.zeek, line 4: &default is not valid for global variables except for tables (&default=0) error in <...>/attr-default-global-set-error.zeek, line 9: &default is not valid for global variables except for tables (&default=10) error in <...>/attr-default-global-set-error.zeek, line 9: &default is not valid for global variables except for tables (&default=9) -error in <...>/attr-default-global-set-error.zeek, line 9: &optional is not valid for global variables (&optional) +error in <...>/attr-default-global-set-error.zeek, line 9: &optional is only valid for record fields (&optional) error in <...>/attr-default-global-set-error.zeek, line 10: &default is not valid for global variables except for tables (&default=set()) diff --git a/testing/btest/Baseline/language.invalid-optional-attr/out b/testing/btest/Baseline/language.invalid-optional-attr/out new file mode 100644 index 0000000000..e862d4bb9b --- /dev/null +++ b/testing/btest/Baseline/language.invalid-optional-attr/out @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/invalid-optional-attr.zeek, line 5: &optional is only valid for record fields (&optional) +error in <...>/invalid-optional-attr.zeek, line 11: &optional is only valid for record fields (&optional) diff --git a/testing/btest/language/invalid-optional-attr.zeek b/testing/btest/language/invalid-optional-attr.zeek new file mode 100644 index 0000000000..338408caf4 --- /dev/null +++ b/testing/btest/language/invalid-optional-attr.zeek @@ -0,0 +1,12 @@ +# @TEST-EXEC-FAIL: zeek -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +# Invalid on globals +global a: int &optional; + +# TODO: Invalid on parameters +function f(a: int &optional) + { + # Invalid in locals + local b: int &optional; + }