This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: compatibility of structs/unions/enums in the middle end


On Wed, Oct 2, 2019 at 12:46 PM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Tue, Oct 1, 2019 at 7:49 PM Uecker, Martin
> <Martin.Uecker@med.uni-goettingen.de> wrote:
> >
> >
> >
> > Hi,
> >
> > I have a proposal for making changes to the rules for
> > compatibility of tagged types in C2X  (N2366). This was
> > received with interest by WG14, so there is a chance
> > that this could get accepted into C2X.
> >
> > In particular, the idea is to make structs (+ unions, enums)
> > with the same tag and the same members compatible. The
> > current C standards says that such structs are compatible
> > between different TUs but not inside the same TU, which
> > is very strange and - as pointed out by Joseph
> > in DR314 - this leads to "interesting" scenarios
> > where types across different TU cannot be partitioned
> > into equivalence classes in a consistent way.
> >
> > The new rules would fix these inconsistencies and also
> > make some useful programming patterns possible: E.g. one
> > could declare structs/union/enums types in a macro so
> > that another invocation produces a compatible type.
> > For example:
> >
> > #define MAYBE(T) struct foo_##T { _Bool flag; T value };
> >
> > MAYBE(int) x = { true, 0 };
> > MAYBE(int) y = x;
> >
> >
> > I am working on a patch for GCC which adds this as an
> > optional feature. So far, I have a working patch to the
> > C front end which changes the concept of type compatibility
> > to match the proposed model. It uses the existing code
> > for type compatibility, so is relatively simple.
> >
> > The question is now how this should interact with the
> > middle end. So far, I have to insert some VIEW_CONVERT_EXPR
> > to avoid "useless type conversion" errors during gimple
> > verification.
> >
> > I am also wonder how to make TBAA do the right thing
> > for the new rules. Currently, GCC assumes 's1p' and 's2p'
> > cannot alias in the following example and outputs '2'
> > in 'f', but this would not be true anymore according
> > to the proposal.
> >
> >
> > #include <stdio.h>
> >
> > typedef struct { int i; } st1;
> > typedef struct { int i; } st2;
> >
> > void f(void* s1v, void* s2v)
> > {
> >   st1 *s1p = s1v;
> >   st2 *s2p = s2v;
> >   s1p->i = 2;
> >   s2p->i = 3;
> >   printf("f: s1p->i = %i\n", s1p->i);
> > }
> >
> > int main()
> > {
> >   st1 s = { .i = 1 };
> >   f(&s, &s);
> >   printf("s.i = %i\n", s.i);
> > }
> >
> > BTW: According to current rules when 'f' is
> > moved into a different TU, there is no UB.
> > As both 'st1'
> > and 'st2' in one TU are compatible
> > to both 'st1' and 'st2' in the other TU there
> > is no UB. Still, GCC
> > incorrectly assumes that
> > 's1p' and 's1p' do not alias.
> >
> >
> > I would appreciate any information about how to
> > approach this.
>
> The frontend either needs to have the same internal
> type representation for both or provide the middle-end
> with unification of compatible types via the TYPE_CANONICAL
> mechanism (that's what the C++ FE does in similar circumstances).
>
> That is, the TBAA machinery relies on TYPE_CANONICAL (TYPE_MAIN_VARIANT (st1))
> == TYPE_CANONICAL (TYPE_MAIN_VARIANT (st2))
> (or requivalent TYPE_MAIN_VARIANT if that's already the case).

Btw, for you example, how do you expect debug information to look like?
Would there be two type definitions that are not related?

Richard.

> Richard.
>
> >
> > Best,
> > Martin
> >


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]