On Thu, May 30, 2019 at 4:28 PM Martin Sebor <mse...@gmail.com> wrote: > > On 5/28/19 3:30 PM, Sean Gillespie wrote: > > This adds a new warning, -Wglobal-constructors, that warns whenever a > > decl requires a global constructor or destructor. This new warning fires > > whenever a thread_local or global variable is declared whose type has a > > non-trivial constructor or destructor. When faced with both a constructor > > and a destructor, the error message mentions the destructor and is only > > fired once. > > > > This warning mirrors the Clang option -Wglobal-constructors, which warns > > on the same thing. -Wglobal-constructors was present in Apple's GCC and > > later made its way into Clang. > > > > Bootstrapped and regression-tested on x86-64 linux, new tests passing. > > I can't tell from the Clang online manual: > > Is the warning meant to trigger just for globals, or for all > objects with static storage duration regardless of scope (i.e., > including namespace-scope objects and static locals and static > class members)? > > "Requires a constructor to initialize" doesn't seem very clear > to me. Is the warning intended to trigger for objects that > require dynamic initialization? If so, then what about dynamic > intialization of objects of trivial types, such as this: > > static int i = std::string ("foo").length (); > > or even > > static int j = strlen (getenv ("TMP")); > > If these aren't meant to be diagnosed then the description should > make it clear (the first one involves a ctor, the second one does > not). But I would think that if the goal is to find sources of > dynamic initialization then diagnosing the above would be useful. > If so, the description should make it clear and tests verifying > that it works should be added. > > Martin
The answer to both of those is yes. Clang warns on both of these with -Wglobal-constructors because the goal of -Wglobal-constructors is to catch and warn against potential life-before-main behavior. Based on Marek's feedback I'm about to push another patch that also warns on your above two examples and adds tests for them. The idea is that any C++-level dynamically initialized globals get warned. Constexpr constructors or things that otherwise can be statically initialized are not warned. Regarding the doc description, how about something like this: "Warns whenever an object with static storage duration requires dynamic initialiation, through global constructors or otherwise." > > PS Dynamic initialization can be optimized into static > initialization, even when it involves a user-defined constructor. > If the purpose of the warning is to find objects that are > dynamically initialized in the sense of the C++ language then > implementing it in the front-end is sufficient. But if the goal > is to detect constructors that will actually run at runtime (i.e., > have a startup cost and may have dependencies on one another) then > it needs to be implemented much later. > Clang sticks to the C++ language definition of dynamic initialization for the purposes of this warning and I think we should as well. Without runtime checks this is a best-effort warning, but it is capable of catching a bunch of the common ways that you can get constructors running on startup, which is the goal. Sean Gillespie