Re: [RFC] Proposal for tagged_by attribute to describe union discriminators
Richard Biener via Gcc <[email protected]> Thu, 16 Jul 2026 13:48:53 +0200
| Newsgroups | gmane.comp.gcc.devel |
|---|---|
| Message-ID | <CAFiYyc0tyj0_V_1cX2tmZS=MjCS-gmNaSzA4557iGyo2UqN-hg@mail.gmail.com> |
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 > > >