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 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).

Richard.

>
> Best,
> Martin
>


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