https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80320
Bug ID: 80320 Summary: Constructor executed twice for the same static member when using -fno-implicit-templates Product: gcc Version: 7.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: abbeyj+gcc at gmail dot com Target Milestone: --- Created attachment 41130 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41130&action=edit Testcase With the attached testcase, the constructor for Foo<int>::bar is run twice in a row with the same `this` pointer both times. bar is a static member of Foo<int>. At exit the destructor is run twice as well. This only happens when using -fno-implicit-templates. $ make g++ -Wall -fno-implicit-templates -c -o main.o main.cpp g++ -Wall -fno-implicit-templates -c -o foo.o foo.cpp g++ main.o foo.o -o double $ ./double Bar this=0x601041 Bar this=0x601041 frob this=0x601041 ~Bar this=0x601041 ~Bar this=0x601041 I would have expected the output to look instead like: $ ./double Bar this=0x601041 frob this=0x601041 ~Bar this=0x601041 foo.cpp explicitly instantiates Foo<int> so I'd expect foo.o to have a call to the constructor. There is one there in __static_initialization_and_destruction_0. Before the call there is a check against "guard variable for Foo<int>::bar". main.cpp only references Foo<int>::bar. Like in foo.o, main.o also calls Bar::Bar() from its __static_initialization_and_destruction_0. Unlike in foo.o, there is no check against "guard variable for Foo<int>::bar". I don't know exactly what's supposed to happen with -fno-implicit-templates and static members. I initially expected that main.o would not try to construct any static members since they were not explicitly instantiated. If that were the case then the static would only be constructed by foo.o and things would work correctly. Possibly that's not the desired behavior and static members are intended to be instantiated implicitly even with -fno-implicit-templates in effect. If that is the case then the generated code seems buggy since it doesn't include the check against the guard variable. I've tested this on various versions of GCC and it occurs on 4.4.7, 4.9.2, 6.3.0 and a copy of 7.0.1 built from trunk so this does not seem like a recent regression.