forked from Imagelibrary/binutils-gdb
libctf: create: addition of non-root types should not return root types
If you add a non-root type to a dict, you should always get a new, unique type ID back, even if a root-visible type with the same name already exists. Unfortunately, if the root-visible type is a forward, and you're adding a non-root-visible struct, union, or enum, the machinery to detect forwards and promote them to the concrete type fires in this case and returns the root-visible type! If this is an enum being inserted hidden because its enumerands conflict with some other enum, this will lead to failure later on: in any case, it's seriously counterintuitive to add a non-root- visible type and get a root-visible one instead. Fix this by checking the root-visible flag properly and only checking for forwards if this type is root-visible. (This may lead to a certain degree of proliferation of non-root-visible forwards: we can add a cleanup pass for those later if needed.) libctf/ * ctf-create.c (ctf_add_sou_sized): Check the root-visible flag when doing forward promotion. (ctf_add_enum_internal): Likewise. (ctf_add_enum_encoded_internal): Likewise.
This commit is contained in:
@@ -1193,7 +1193,7 @@ ctf_add_sou_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
|
||||
return (ctf_set_errno (fp, ECTF_NOPARENT));
|
||||
|
||||
/* Promote root-visible forwards to structs/unions. */
|
||||
if (name != NULL)
|
||||
if (name != NULL && root_flag == CTF_ADD_ROOT)
|
||||
type = ctf_lookup_by_rawname (fp, kind, name);
|
||||
|
||||
if (type > 0)
|
||||
@@ -1269,7 +1269,7 @@ ctf_add_enum_internal (ctf_dict_t *fp, uint32_t flag, const char *name,
|
||||
return (ctf_set_errno (fp, ECTF_NOPARENT));
|
||||
|
||||
/* Promote root-visible forwards to enums. */
|
||||
if (name != NULL)
|
||||
if (name != NULL && flag == CTF_ADD_ROOT)
|
||||
type = ctf_lookup_by_rawname (fp, kind, name);
|
||||
|
||||
/* Prohibit promotion if this type was ctf_open()ed. */
|
||||
@@ -1322,7 +1322,7 @@ ctf_add_enum_encoded_internal (ctf_dict_t *fp, uint32_t flag, const char *name,
|
||||
enums or forwards to them. (This includes other slices: you cannot slice a
|
||||
slice, which would be a useless thing to do anyway.) */
|
||||
|
||||
if (name != NULL)
|
||||
if (name != NULL && flag == CTF_ADD_ROOT)
|
||||
type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name);
|
||||
|
||||
if (type != 0)
|
||||
|
||||
Reference in New Issue
Block a user