This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/80320] New: Constructor executed twice for the same static member when using -fno-implicit-templates


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]