From ab87ba97865a2892a6fa71adfaef5270ee3c7576 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 3 Apr 2025 19:28:01 +0200 Subject: [PATCH] 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::id::find_type()`. It also means that enum identifiers added via redef later would have a different TypePtr than those in the initial pointer. --- src/Var.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Var.cc b/src/Var.cc index e17e2dc15a..44ced49665 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -369,9 +369,18 @@ void add_type(ID* id, TypePtr t, std::unique_ptr> 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.