From ec4913ac18ba930cc82cd2508eec0dca2cc01424 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 8 Jul 2019 14:31:51 -0700 Subject: [PATCH] GH-157: Mark some attributes as not allowed for global variables --- src/Attr.cc | 23 +++++++++++++++---- src/Attr.h | 3 ++- src/Expr.cc | 4 ++-- src/ID.cc | 6 ++--- src/Type.cc | 4 ++-- src/Var.cc | 6 ++--- .../out | 7 ++++-- .../attr-default-global-set-error.zeek | 5 ++++ 8 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Attr.cc b/src/Attr.cc index 36050d2262..4231a3fa29 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -130,11 +130,12 @@ void Attr::AddTag(ODesc* d) const d->Add(attr_name(Tag())); } -Attributes::Attributes(attr_list* a, BroType* t, bool arg_in_record) +Attributes::Attributes(attr_list* a, BroType* t, bool arg_in_record, bool is_global) { attrs = new attr_list(a->length()); type = t->Ref(); in_record = arg_in_record; + global_var = is_global; SetLocationInfo(&start_location, &end_location); @@ -250,10 +251,14 @@ void Attributes::CheckAttr(Attr* a) { switch ( a->Tag() ) { case ATTR_DEPRECATED: - case ATTR_OPTIONAL: case ATTR_REDEF: break; + case ATTR_OPTIONAL: + if ( global_var ) + Error("&optional is not valid for global variables"); + break; + case ATTR_ADD_FUNC: case ATTR_DEL_FUNC: { @@ -283,6 +288,15 @@ void Attributes::CheckAttr(Attr* a) case ATTR_DEFAULT: { + // &default is allowed for global tables, since it's used in initialization + // of table fields. it's not allowed otherwise. + // + if ( global_var && ! type->IsSet() && type->Tag() != TYPE_TABLE ) + { + Error("&default is not valid for global variables"); + break; + } + BroType* atype = a->AttrExpr()->Type(); if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) @@ -408,11 +422,12 @@ void Attributes::CheckAttr(Attr* a) } } -#if 0 //### not easy to test this w/o knowing the ID. - if ( ! IsGlobal() ) +#if 0 + if ( ! global_var ) Error("expiration not supported for local variables"); #endif + break; case ATTR_EXPIRE_FUNC: diff --git a/src/Attr.h b/src/Attr.h index efbac63747..09a8266929 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -77,7 +77,7 @@ protected: // Manages a collection of attributes. class Attributes : public BroObj { public: - Attributes(attr_list* a, BroType* t, bool in_record); + Attributes(attr_list* a, BroType* t, bool in_record, bool is_global); ~Attributes() override; void AddAttr(Attr* a); @@ -101,6 +101,7 @@ protected: BroType* type; attr_list* attrs; bool in_record; + bool global_var; }; #endif diff --git a/src/Expr.cc b/src/Expr.cc index 450ac73437..7235b14d35 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3133,7 +3133,7 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list, } } - attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : 0; type_list* indices = type->AsTableType()->Indices()->Types(); const expr_list& cle = constructor_list->Exprs(); @@ -3240,7 +3240,7 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list, else if ( type->Tag() != TYPE_TABLE || ! type->AsTableType()->IsSet() ) SetError("values in set(...) constructor do not specify a set"); - attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, type, false, false) : 0; type_list* indices = type->AsTableType()->Indices()->Types(); expr_list& cle = constructor_list->Exprs(); diff --git a/src/ID.cc b/src/ID.cc index c249697b4d..6029cb9862 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -181,7 +181,7 @@ void ID::UpdateValAttrs() TypeDecl* fd = rt->FieldDecl(i); if ( ! fd->attrs ) - fd->attrs = new Attributes(new attr_list, rt->FieldType(i), true); + fd->attrs = new Attributes(new attr_list, rt->FieldType(i), true, IsGlobal()); fd->attrs->AddAttr(new Attr(ATTR_LOG)); } @@ -195,7 +195,7 @@ void ID::MakeDeprecated(Expr* deprecation) return; attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, deprecation)}; - AddAttrs(new Attributes(attr, Type(), false)); + AddAttrs(new Attributes(attr, Type(), false, IsGlobal())); } string ID::GetDeprecationWarning() const @@ -245,7 +245,7 @@ void ID::SetOption() if ( ! IsRedefinable() ) { attr_list* attr = new attr_list{new Attr(ATTR_REDEF)}; - AddAttrs(new Attributes(attr, Type(), false)); + AddAttrs(new Attributes(attr, Type(), false, IsGlobal())); } } diff --git a/src/Type.cc b/src/Type.cc index 60461e026f..efe3d254c5 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -650,7 +650,7 @@ void FuncType::DescribeReST(ODesc* d, bool roles_only) const TypeDecl::TypeDecl(BroType* t, const char* i, attr_list* arg_attrs, bool in_record) { type = t; - attrs = arg_attrs ? new Attributes(arg_attrs, t, in_record) : 0; + attrs = arg_attrs ? new Attributes(arg_attrs, t, in_record, false) : 0; id = i; } @@ -841,7 +841,7 @@ const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) if ( log ) { if ( ! td->attrs ) - td->attrs = new Attributes(new attr_list, td->type, true); + td->attrs = new Attributes(new attr_list, td->type, true, false); td->attrs->AddAttr(new Attr(ATTR_LOG)); } diff --git a/src/Var.cc b/src/Var.cc index 74cfee291f..3f8f411dc3 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -108,7 +108,7 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init, id->SetType(t); if ( attr ) - id->AddAttrs(new Attributes(attr, t, false)); + id->AddAttrs(new Attributes(attr, t, false, id->IsGlobal())); if ( init ) { @@ -286,7 +286,7 @@ void add_type(ID* id, BroType* t, attr_list* attr) id->MakeType(); if ( attr ) - id->SetAttrs(new Attributes(attr, tnew, false)); + id->SetAttrs(new Attributes(attr, tnew, false, false)); } static void transfer_arg_defaults(RecordType* args, RecordType* recv) @@ -304,7 +304,7 @@ static void transfer_arg_defaults(RecordType* args, RecordType* recv) if ( ! recv_i->attrs ) { attr_list* a = new attr_list{def}; - recv_i->attrs = new Attributes(a, recv_i->type, true); + recv_i->attrs = new Attributes(a, recv_i->type, true, false); } else if ( ! recv_i->attrs->FindAttr(ATTR_DEFAULT) ) 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 6f3fd63d4f..55c70a62ff 100644 --- a/testing/btest/Baseline/language.attr-default-global-set-error/out +++ b/testing/btest/Baseline/language.attr-default-global-set-error/out @@ -1,2 +1,5 @@ -error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 4: arithmetic mixed with non-arithmetic (set[string] and 0) -error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 4: &default value has inconsistent type (0 and set[string]) +error in /Users/tim/Desktop/projects/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 4: arithmetic mixed with non-arithmetic (set[string] and 0) +error in /Users/tim/Desktop/projects/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 4: &default value has inconsistent type (0 and set[string]) +error in /Users/tim/Desktop/projects/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 9: &default is not valid for global variables (&default=10) +error in /Users/tim/Desktop/projects/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 9: &default is not valid for global variables (&optional, &default=9) +error in /Users/tim/Desktop/projects/zeek/testing/btest/.tmp/language.attr-default-global-set-error/attr-default-global-set-error.zeek, line 9: &optional is not valid for global variables (&optional, &default=9, &optional) diff --git a/testing/btest/language/attr-default-global-set-error.zeek b/testing/btest/language/attr-default-global-set-error.zeek index 515c71fc24..05ae6b1722 100644 --- a/testing/btest/language/attr-default-global-set-error.zeek +++ b/testing/btest/language/attr-default-global-set-error.zeek @@ -2,3 +2,8 @@ # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out global ss: set[string] &default=0; +global d: count &default = 10 + &default = 9 + &optional + &log + &add_func = function(): count { return 3; };