[PATCH] D74361: [Clang] Undef attribute for global variables

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 2 12:29:25 PST 2020


rjmccall added inline comments.


================
Comment at: clang/test/CodeGenCXX/attr-loader-uninitialized.cpp:23
+// CHECK: @nominally_value_init = global i32 undef
+int nominally_value_init  [[clang::loader_uninitialized]] = 4;
+
----------------
JonChesterfield wrote:
> Quuxplusone wrote:
> > This test case is identical to line 36 of clang/test/Sema/attr-loader-uninitialized.cpp, where you say you don't want it to compile at all.
> > 
> > I think you need a clearer idea of how this interacts with initializers. Is it merely supposed to eliminate the //zero-initialization// that happens before the user-specified construction/initialization, or is it supposed to compete with the user-specified construction/initialization?
> > 
> > That is, for
> > 
> >     nontrivial unt [[clang::loader_uninitialized]];
> > 
> > is it merely supposed to call `unt::unt()` on a chunk of undef memory (instead of the usual chunk of zeroed memory), or is it supposed to skip the constructor entirely? And for
> > 
> >     int x [[clang::loader_uninitialized]] = foo();
> > 
> > is it merely supposed to call `foo()` and assign the result to a chunk of undef memory (instead of the usual chunk of zeroed memory), or is it supposed to skip the initialization entirely?
> I think you commented while the first working piece of sema landed. My thinking is relatively clear but my understanding of clang's semantic analysis is a work in progress!
> 
> Initializers (`= foo()`) are straightforward. Error on the basis that the attribute effectively means `= undef`, and one should not have two initializers. A test case is now added for that (and now passes).
> 
> The codegen I want for a default constructed global marked with this variable is:
> - global variable allocated, with undef as the original value
> - default constructor call synthesized
> - said default constructor set up for invocation from crt, before main, writing over the undef value
> 
> Where the default constructor can be optimized as usual, e.g. if it always writes a constant, we can init with that constant instead of the undef and elide the constructor.
> 
> I don't have that actually working yet - the constructor call is not being emitted, so we just have the undef global.
> 
> I think it's important to distinguish between the values of the bits when the program is loaded and whether constructor/destructors are called, as one could want any combination of the two.
I think Arthur is suggesting that it would be useful to allow the attribute to be used in conjunction with an initializer in C++, since if the initializer has to be run dynamically, we can still meaningfully suppress the static zero-initialization.   That is, we've accepted that it's useful to do this when *default-initializing* a global, but it's actually useful when doing *any* kind of dynamic initialization.

Maybe we can leave it as an error in C++ when the initializer is a constant expression.  Although that might be unnecessarily brittle if e.g. the constructor is `constexpr` in one library version but not another.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74361/new/

https://reviews.llvm.org/D74361





More information about the cfe-commits mailing list