rjmccall added inline comments.
================ Comment at: lib/Sema/SemaDecl.cpp:12053 + NTCUC_UninitAutoVar); } + ---------------- ahatanak wrote: > rjmccall wrote: > > Please add a comment explaining why this is specific to local variables. > I was trying to explain why this should be specific to local variables and > realized that it's not clear to me whether it should be. > > Suppose there is a union with two fields that are both non-trivial: > > ``` > union U { > Type A a; > Type B a; > }; > > U global; > ``` > > In this case, is value-initialization (which is essentially > default-initialization plus a bunch of zero-initialization as per our > previous discussion) used to initialize `global`? If so, should we reject the > code since it requires default-initialization? It should be fine if we can > assume default-initialization means zero-initialization for non-trivial types > in C, but what if `TypeA` or `TypeB` requires initializing to a non-zero > value? Yeah, the default-initialization dimension of this problem is interesting. The C++ rule makes sense for C++ because default initialization of a C++ class requires an actual, arbitrary-side-effects constructor call, which of course you can't reasonably do implicitly for a union member. As discussed previously, non-trivial C types can presumably always be default-initialized with a constant bit pattern. That means that, as long as we can do any initialization work at all, then it's in principle not a problem as long as the bit pattern is the same for all the union members requiring non-trivial initialization (and in particular if there's only one such member). So it's just like you say, we *could* just initialize such unions conservatively as long as two different members don't require inconsistent patterns, which in practice they currently never do. That's all true independent of storage duration — if we can write that pattern into a global, we can write into a local. The only caveat is that a semantic need for non-trivial default initialization almost certainly means that there's a semantic need for non-trivial destruction as well, which of course can't be done on a local union (but isn't a problem for a global because we just don't destroy them). On the other hand, on a language level it's much simpler to just say that we can't default-initialize a union of any storage duration if it has a non-trivial member, and then the language rule doesn't depend on bit-level representations. If there's interest, we can look into weakening that rule later by saying that e.g. it's possible to default-initialize a union with at most one non-trivial member. Apropos, do we consider unions with non-trivial members to be non-trivial members for the purposes of enclosing unions? Seems like we should. Probably the most sensible way to handle that is to also flag the union as being non-trivial in a dimension if it has a member that's non-trivial in that dimension (which might also let you fast-path some of the checking you need to do). Essentially, we'd consider the case where copying is impossible to be a subset of the case where copying is non-trivial. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63753/new/ https://reviews.llvm.org/D63753 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits