On Thu, Jul 16, 2026 at 10:01 AM Martin Uecker <[email protected]> wrote:
>
> Am Donnerstag, dem 16.07.2026 um 09:38 +0200 schrieb Richard Biener via Gcc:
> > On Wed, Jul 15, 2026 at 11:19 PM Ashton Warner via Gcc <[email protected]>
> > wrote:
> > >
> > > 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?
> >
> > GCC has QUAL_UNION_TYPE for this (for a corresponding Ada feature,
> > but IIRC Modula also has that). It would be nice to design the extension
> > in a way to emit that given that would make it possible for the GIMPLE
> > frontend (which builds upon the C parser and type machinery) to expose
> > QUAL_UNION_TYPE.
>
> Is this compatible with an attribute that is meant to preserve
> the ABI of existing code?
I think there's no ABI difference between QUAL_UNION_TYPE and UNION_TYPE.
There is just the opportunity to perform runtime checking when you
access <union>.x (assert 'x' is active) and you can access <union>,
magically getting the active member, but that would require some
polymorphism I guess. I'm not actually sure how Ada uses it.
Basically each union member has a "is-this-active" predicate which can
refer to for example fields in an outer object via PLACEHODER_EXPRs.
So sth like
struct X {
int tag;
union {
int a __attribute__((qual(tag == 1)));
double b __attribute__((qual(tag == 2)));
};
int k;
};
note I think the twist with the above example is that if the union is
a QUAL_UNION_TYPE then the actual size of a struct X object
depends on which union element is active, so an access to 'k'
would be of variable-offset.
Eric, please correct me if I'm wrong.
Richard.
>
> Martin
>
> >