Var/add_type: Do not clone EnumType when declared for the first time

EnumType receives the name into its constructor. Even for the  first declaration
the name is not empty and instead the same as the identifier's name. Due to that,
add_type() previously took the else path and created a shallow clone of the
initial type instead of using it. This lead to buggy behavior where enum value
identifiers declared within an enum's first body have a different TypePtr
associated than the one that is found via `zeek:🆔:find_type()`. It also
means that enum identifiers added via redef later would have a different
TypePtr than those in the initial pointer.
This commit is contained in:
Arne Welzel 2025-04-03 19:28:01 +02:00
parent 18597ea49c
commit ab87ba9786

View file

@ -369,9 +369,18 @@ void add_type(ID* id, TypePtr t, std::unique_ptr<std::vector<AttrPtr>> attr) {
TypePtr tnew;
if ( (t->Tag() == TYPE_RECORD || t->Tag() == TYPE_ENUM) && old_type_name.empty() )
if ( (t->Tag() == TYPE_RECORD || t->Tag() == TYPE_ENUM) &&
(old_type_name.empty() || old_type_name == new_type_name) ) {
// An extensible type (record/enum) being declared for first time.
//
// Enum types are initialized with the same name as their identifier
// when declared for the first time, double check that here.
if ( t->Tag() == TYPE_ENUM && new_type_name != old_type_name )
reporter->InternalError("enum type has unexpected names: '%s' and '%s'", old_type_name.c_str(),
new_type_name.c_str());
tnew = std::move(t);
}
else {
// If the old type is an error or the old type doesn't exist, then return
// an error instead of trying to clone it.