diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2024-06-11 20:33:03 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2024-06-18 13:20:32 +0100 |
commit | 6e09d4a6e6e62e585fe1237a0094f80f8aeef2fa (patch) | |
tree | 02ac80c35cb96b1acad21353df5d1b33aa114bbe /include | |
parent | 9f0fb75b8e121a93b0f63dd823fa86ffd44e8e5d (diff) | |
download | gdb-6e09d4a6e6e62e585fe1237a0094f80f8aeef2fa.zip gdb-6e09d4a6e6e62e585fe1237a0094f80f8aeef2fa.tar.gz gdb-6e09d4a6e6e62e585fe1237a0094f80f8aeef2fa.tar.bz2 |
libctf: prohibit addition of enums with overlapping enumerator constants
libctf has long prohibited addition of enums with overlapping constants in a
single enum, but now that we are properly considering enums with overlapping
constants to be conflciting types, we can go further and prohibit addition
of enumeration constants to a dict if they already exist in any enum in that
dict: the same rules as C itself.
We do this in a fashion vaguely similar to what we just did in the
deduplicator, by considering enumeration constants as identifiers and adding
them to the core type/identifier namespace, ctf_dict_t.ctf_names. This is a
little fiddly, because we do not want to prohibit opening of existing dicts
into which the deduplicator has stuffed enums with overlapping constants!
We just want to prohibit the addition of *new* enumerators that violate that
rule. Even then, it's fine to add overlapping enumerator constants as long
as at least one of them is in a non-root type. (This is essential for
proper deduplicator operation in cu-mapped mode, where multiple compilation
units can be smashed into one dict, with conflicting types marked as
hidden: these types may well contain overlapping enumerators.)
So, at open time, keep track of all enums observed, then do a third pass
through the enums alone, adding each enumerator either to the ctf_names
table as a mapping from the enumerator name to the enum it is part of (if
not already present), or to a new ctf_conflicting_enums hashtable that
tracks observed duplicates. (The latter is not used yet, but will be soon.)
(We need to do a third pass because it's quite possible to have an enum
containing an enumerator FOO followed by a type FOO: since they're processed
in order, the enumerator would be processed before the type, and at that
stage it seems nonconflicting. The easiest fix is to run through the
enumerators after all type names are interned.)
At ctf_add_enumerator time, if the enumerator to which we are adding a type
is root-visible, check for an already-present name and error out if found,
then intern the new name in the ctf_names table as is done at open time.
(We retain the existing code which scans the enum itself for duplicates
because it is still an error to add an enumerator twice to a
non-root-visible enum type; but we only need to do this if the enum is
non-root-visible, so the cost of enum addition is reduced.)
Tested in an upcoming commit.
libctf/
* ctf-impl.h (ctf_dict_t) <ctf_names>: Augment comment.
<ctf_conflicting_enums>: New.
(ctf_dynset_elements): New.
* ctf-hash.c (ctf_dynset_elements): Implement it.
* ctf-open.c (init_static_types): Split body into...
(init_static_types_internal): ... here. Count enumerators;
keep track of observed enums in pass 2; populate ctf_names and
ctf_conflicting_enums with enumerators in a third pass.
(ctf_dict_close): Free ctf_conflicting_enums.
* ctf-create.c (ctf_add_enumerator): Prohibit addition of duplicate
enumerators in root-visible enum types.
include/
* ctf-api.h (CTF_ADD_NONROOT): Describe what non-rootness
means for enumeration constants.
(ctf_add_enumerator): The name is not a misnomer.
We now require that enumerators have unique names.
Document the non-rootness of enumerators.
Diffstat (limited to 'include')
-rw-r--r-- | include/ctf-api.h | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/include/ctf-api.h b/include/ctf-api.h index 85734af..d7bdbdd 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -268,9 +268,11 @@ _CTF_ERRORS #endif /* Dynamic CTF containers can be created using ctf_create. The ctf_add_* - routines can be used to add new definitions to the dynamic container. - New types are labeled as root or non-root to determine whether they are - visible at the top-level program scope when subsequently doing a lookup. */ + routines can be used to add new definitions to the dynamic container. New + types are labeled as root or non-root to determine whether they are visible + at the top-level program scope when subsequently doing a lookup. + (Identifiers contained within non-root types, like enumeration constants, are + also not visible.) */ #define CTF_ADD_NONROOT 0 /* Type only visible in nested scope. */ #define CTF_ADD_ROOT 1 /* Type visible at top-level scope. */ @@ -785,9 +787,8 @@ extern ctf_id_t ctf_add_union_sized (ctf_dict_t *, uint32_t, const char *, extern ctf_id_t ctf_add_unknown (ctf_dict_t *, uint32_t, const char *); extern ctf_id_t ctf_add_volatile (ctf_dict_t *, uint32_t, ctf_id_t); -/* Add an enumerator to an enum (the name is a misnomer). We do not currently - validate that enumerators have unique names, even though C requires it: in - future this may change. */ +/* Add an enumerator to an enum. If the enum is non-root, so are all the + constants added to it by ctf_add_enumerator. */ extern int ctf_add_enumerator (ctf_dict_t *, ctf_id_t, const char *, int); |