[PATCH] D63753: [Sema] Instead of rejecting C unions with non-trivial fields, detect attempts to destruct/initialize/copy them.
John McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 26 22:00:57 PDT 2019
rjmccall added inline comments.
================
Comment at: lib/Sema/SemaDecl.cpp:11085
+ if (isa<ImplicitValueInitExpr>(I))
+ continue;
+ if (auto E = dyn_cast<InitListExpr>(I))
----------------
ahatanak wrote:
> rjmccall wrote:
> > Why is this okay? Don't we need to check default-initialization for these?
> I didn't consider an `ImplicitValueInitExpr` to be a default-initialization since IRGen currently emits a memcpy to initialize the field instead of calling a synthesized default-initialization function as it does when a local variable that's a non-trivial C struct is declared without an initializer.
>
> ```
> typedef struct {
> id f0, f1;
> } S0 ;
>
> typedef struct {
> S0 s0;
> int f2;
> } S;
>
> void test(void) {
> // emits a memcpy of a global constant.
> S s = { .f2 = 1 };
> }
> ```
>
> It's not clear to me whether this is a default-initialization, but if it is, we should check default-initialization here and IRGen should be fixed to emit a call to the default-initialization function.
C does not use the terms "default-initialization" and "value-initialization", but the the initialization performed for static/thread storage duration objects generally matches what C++ would call value-initialization. These rules are laid out in section 6.7.9 of the standard, which also includes the following in its description of the rules for list-initializations of aggregates (regardless of their storage duration):
> p19: ...all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.
So `s.s0` must be initialized as if a static object (in C++ terms, value-initialized), not left with an indeterminate value like an object of automatic storage duration without an initializer would be (in C++ terms, default-initialized).
I assume that the default-initialization function for a non-trivial C struct only initializes the fields that have non-trivial default-initialization. That's not good enough for value-initialization, which is required to recursively value-initialize *all* of the fields (and even zero-initialize any padding). Note that that's the *only* difference between these two kinds of initialization. Furthermore, if you think about what default-initialization actually means for all our leaf non-trivial C types, it's just assigning a predictable bit-pattern (e.g. a null pointer for ARC's `__strong` and `__weak` references), not doing anything that requires executing tailored code at runtime. So here's what that tells us:
- We can't call the default-initialization function because it might leave trivial fields uninitialized (in general, although `struct S0` in your example doesn't have any, so effectively it does a full value-initialization).
- `memcpy` from a global constant is always a valid implementation of value-initialization for non-trivial C types. It's also a valid implementation for default-implementation; it just might do more than it really needs to. (In the case of `struct S0`, it would be *more efficient* to use `memset`, but `memcpy` is still *valid*.)
Now, maybe someday we'll add a non-trivial C type that really requires non-trivial code to initialize, but I doubt we'd want to, because we'd have to forbid e.g. declaring global variables of that type, and we wouldn't have a simple answer for telling people how to properly initialize a dynamically-allocated object. Even if we do, we can wait until then to generalize.
- Regardless, yes, this is a value-initialization and so it should check whether we can value-initialize the type. Since value-initialization just means default-initialization plus a bunch of zero-initialization (which we can assume we can always do), that just means checking whether we can default-initialize the type.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63753/new/
https://reviews.llvm.org/D63753
More information about the cfe-commits
mailing list