Allow duplicate attributes in full redefs

This commit is contained in:
Tim Wojtulewicz 2020-08-28 09:55:40 -07:00
parent 9b2f26c0aa
commit 9106f3f722
5 changed files with 18 additions and 15 deletions

View file

@ -193,7 +193,7 @@ Attributes::Attributes(std::vector<AttrPtr> a,
AddAttr(std::move(attr)); AddAttr(std::move(attr));
} }
void Attributes::AddAttr(AttrPtr attr) void Attributes::AddAttr(AttrPtr attr, bool is_redef)
{ {
auto acceptable_duplicate_tag = [&](const AttrPtr& attr, const AttrPtr& existing) -> bool auto acceptable_duplicate_tag = [&](const AttrPtr& attr, const AttrPtr& existing) -> bool
{ {
@ -216,9 +216,12 @@ void Attributes::AddAttr(AttrPtr attr)
// Display a warning for duplicated tags on a type. &log tags are intentionally // Display a warning for duplicated tags on a type. &log tags are intentionally
// ignored here because duplicate log tags on record types are valid, and don't // ignored here because duplicate log tags on record types are valid, and don't
// cause any significant breakage for other types. // cause any significant breakage for other types.
if ( ! is_redef )
{
auto existing = Find(attr->Tag()); auto existing = Find(attr->Tag());
if ( existing && ! acceptable_duplicate_tag(attr, existing) ) if ( existing && ! acceptable_duplicate_tag(attr, existing) )
reporter->Error("Duplicate %s tag is ambiguous", attr_name(attr->Tag())); reporter->Error("Duplicate %s tag is ambiguous", attr_name(attr->Tag()));
}
// We overwrite old attributes by deleting them first. // We overwrite old attributes by deleting them first.
RemoveAttr(attr->Tag()); RemoveAttr(attr->Tag());
@ -249,16 +252,16 @@ void Attributes::AddAttr(AttrPtr attr)
} }
} }
void Attributes::AddAttrs(const AttributesPtr& a) void Attributes::AddAttrs(const AttributesPtr& a, bool is_redef)
{ {
for ( const auto& attr : a->GetAttrs() ) for ( const auto& attr : a->GetAttrs() )
AddAttr(attr); AddAttr(attr, is_redef);
} }
void Attributes::AddAttrs(Attributes* a) void Attributes::AddAttrs(Attributes* a, bool is_redef)
{ {
for ( const auto& attr : a->GetAttrs() ) for ( const auto& attr : a->GetAttrs() )
AddAttr(attr); AddAttr(attr, is_redef);
Unref(a); Unref(a);
} }

View file

@ -115,12 +115,12 @@ public:
~Attributes() override = default; ~Attributes() override = default;
void AddAttr(AttrPtr a); void AddAttr(AttrPtr a, bool is_redef = false);
void AddAttrs(const AttributesPtr& a); void AddAttrs(const AttributesPtr& a, bool is_redef = false);
[[deprecated("Remove in v4.1. Pass IntrusivePtr instead.")]] [[deprecated("Remove in v4.1. Pass IntrusivePtr instead.")]]
void AddAttrs(Attributes* a); // Unref's 'a' when done void AddAttrs(Attributes* a, bool is_redef = false); // Unref's 'a' when done
[[deprecated("Remove in v4.1. Use Find().")]] [[deprecated("Remove in v4.1. Use Find().")]]
Attr* FindAttr(AttrTag t) const; Attr* FindAttr(AttrTag t) const;

View file

@ -314,10 +314,10 @@ std::string ID::GetDeprecationWarning() const
return zeek::util::fmt("deprecated (%s): %s", Name(), result.c_str()); return zeek::util::fmt("deprecated (%s): %s", Name(), result.c_str());
} }
void ID::AddAttrs(AttributesPtr a) void ID::AddAttrs(AttributesPtr a, bool is_redef)
{ {
if ( attrs ) if ( attrs )
attrs->AddAttrs(a); attrs->AddAttrs(a, is_redef);
else else
attrs = std::move(a); attrs = std::move(a);

View file

@ -121,7 +121,7 @@ public:
bool IsRedefinable() const; bool IsRedefinable() const;
void SetAttrs(AttributesPtr attr); void SetAttrs(AttributesPtr attr);
void AddAttrs(AttributesPtr attr); void AddAttrs(AttributesPtr attr, bool is_redef = false);
void RemoveAttr(AttrTag a); void RemoveAttr(AttrTag a);
void UpdateValAttrs(); void UpdateValAttrs();

View file

@ -213,7 +213,7 @@ static void make_var(const zeek::detail::IDPtr& id, zeek::TypePtr t,
id->SetType(t); id->SetType(t);
if ( attr ) if ( attr )
id->AddAttrs(zeek::make_intrusive<zeek::detail::Attributes>(std::move(*attr), t, false, id->IsGlobal())); id->AddAttrs(zeek::make_intrusive<zeek::detail::Attributes>(std::move(*attr), t, false, id->IsGlobal()), dt == VAR_REDEF);
if ( init ) if ( init )
{ {