Hello,
I would like to discuss the possibility of adding a GCC attribute for
describing tagged unions (discriminated unions) to improve static
analysis diagnostics.
The motivation is to allow programmers to explicitly describe a
relationship between an enum discriminator and a union member. C has a
common pattern of representing variants using a struct containing an
enum and a union:
enum num_type {
T_INT,
T_FLOAT,
};
struct number {
enum num_type type;
union {
int ival;
float fval;
};
};
I propose the GCC attribute __attribute__((tagged_by(...))) with the
following syntax:
tagged_by(discriminator, mapping-list)
where:
- discriminator is an identifier
- mapping-list is a comma-separated list of one or more mappings.
- Each mapping has the form:
(enumerator, union-member)
For example:
struct number {
enum num_type type;
union {
int ival;
float fval;
} __attribute__((tagged_by(type,
(T_INT, ival),
(T_FLOAT, fval)
)));
};
The mapping is intentionally explicit rather than inferred from the
declaration order of enum values and union members. This avoids
changing the meaning of the attribute if either the enum or union
members are reordered.
The attribute does not change the representation or runtime behaviour
of the union. It provides additional information that GCC can use for
diagnostics and static analysis.
For example:
struct number n;
n.type = T_INT;
n.fval = 1.0f;
could produce a diagnostic because fval is not the member associated
with the current discriminator value.
The implementation should diagnose invalid mappings, such as an
enumerator that is not part of the discriminator's enum type or a
member that does not exist in the union.
The attribute is intended to provide semantic information in a similar
way to existing attributes such as counted_by, where the compiler is
given information about a relationship that already exists in the
program.
Open questions:
- How should enumerators without an associated union member be
represented? One possibility is allowing a mapping without a member,
for example (T_UNKNOWN), to explicitly indicate that an enumerator
represents a valid discriminator state with no active union member.
Enumerators that are not mentioned in the attribute could then be
diagnosed.
- Should diagnostics based on this attribute be implemented as part of
existing warning infrastructure, -fanalyzer, or another analysis
pass?
- Could this information be useful to future runtime checking tools?
- Are there existing GCC mechanisms that overlap with this
functionality?
- Are there additional constraints or semantics that would be needed
for GCC to implement this attribute?