On Wed, Oct 2, 2019 at 12:46 PM Richard Biener <richard.guent...@gmail.com> wrote: > > On Tue, Oct 1, 2019 at 7:49 PM Uecker, Martin > <martin.uec...@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 > >