https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110715

            Bug ID: 110715
           Summary: Static thread_local unique_ptrs must be defined in the
                    same order as they were declared when using
                    -ftest-coverage else get error 'function starts on a
                    higher line number than it ends'
           Product: gcc
           Version: 13.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: obi.phil+gcc at googlemail dot com
  Target Milestone: ---

Created attachment 55568
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55568&action=edit
Output from g++ -v --save-temps

Consider the following minimum reproducible example:

-----------------------------------------------------------------------
#include <memory>

template<typename T>
class Base
{
 public:
  Base()
  {
    count = std::make_unique<int>(0);
    another = std::make_unique<int>(0);
  }

  virtual ~Base() { }

  static thread_local std::unique_ptr<int> count;
  static thread_local std::unique_ptr<int> another;
};

#ifdef BREAK
template <class T> thread_local std::unique_ptr<int> Base<T>::another(nullptr);
#endif
template <class T> thread_local std::unique_ptr<int> Base<T>::count(nullptr);
#ifndef BREAK
template <class T> thread_local std::unique_ptr<int> Base<T>::another(nullptr);
#endif

class Foo : public Base<Foo>
{
 public:
  Foo() { }
  virtual ~Foo() { }
};

int main()
{
  Foo a;
  return 0;
}
-----------------------------------------------------------------------

When compiled with my usual compiler options (with either -DBREAK or without
it) it compiles fine on OEL9 x86_64 (kernel 5.14.0-162.6.1.el9_1.x86_64).
However when compiled with -ftest-coverage (and -DBREAK) I get the error:

-----------------------------------------------------------------------
TemplateTest.cpp: In function ‘void __tls_init()’:
TemplateTest.cpp:22:54: error: function starts on a higher line number than it
ends [-Werror=coverage-invalid-line-number]
   22 | template <class T> thread_local std::unique_ptr<int>
Base<T>::count(nullptr);
      |                                                      ^~~~~~~
TemplateTest.cpp: In function ‘std::unique_ptr<int>&
_ZTWN4BaseI3FooE5countE()’:
TemplateTest.cpp:22:54: error: function starts on a higher line number than it
ends [-Werror=coverage-invalid-line-number]
-----------------------------------------------------------------------

The newer GCC versions appear to require the static thread_local member
variables to be defined in the same order they are declared. However I've also
seen other instances when trying to create the MRE whereby using the arguments
in a different order to the 'declared' order causes the same error. I have so
far been unable to recreate these issues in an MRE however.

I have validated that this occurs with GCC 13.1.1, 12.2.1, and 12.1.1. It does
not occur when using GCC 11.3.1 or 8.3.1.

The full compilation arguments I've used are:
c++ -v --save-temps -DBREAK -Werror -Wall -Wextra -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations -fprofile-arcs -ftest-coverage -o a.out
TemplateTest.cpp
And I have uploaded the .ii output file it created as an attachment, but please
let me know if you want more information. Here is the output from the command
above:

-----------------------------------------------------------------------
Using built-in specs.
COLLECT_GCC=c++
COLLECT_LTO_WRAPPER=/opt/rh/gcc-toolset-13/root/usr/libexec/gcc/x86_64-redhat-linux/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,lto --prefix=/opt/rh/gcc-toolset-13/root/usr
--mandir=/opt/rh/gcc-toolset-13/root/usr/share/man
--infodir=/opt/rh/gcc-toolset-13/root/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --enable-libstdcxx-backtrace
--with-libstdcxx-zoneinfo=/opt/rh/gcc-toolset-13/root/usr/share/zoneinfo
--with-linker-hash-style=gnu --enable-plugin --enable-initfini-array
--without-isl --enable-offload-targets=nvptx-none --without-cuda-driver
--enable-offload-defaulted --enable-gnu-indirect-function --enable-cet
--with-tune=generic --with-arch_64=x86-64-v2 --with-arch_32=x86-64
--build=x86_64-redhat-linux --with-build-config=bootstrap-lto
--enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.1.1 20230614 (Red Hat 13.1.1-4) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-D' 'BREAK' '-Werror' '-Wall' '-Wextra'
'-fno-strict-aliasing' '-fwrapv' '-fno-aggressive-loop-optimizations'
'-fprofile-arcs' '-ftest-coverage' '-o' 'a.out' '-shared-libgcc'
'-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'a-'
 /opt/rh/gcc-toolset-13/root/usr/libexec/gcc/x86_64-redhat-linux/13/cc1plus -E
-quiet -v -D_GNU_SOURCE -D BREAK TemplateTest.cpp -mtune=generic
-march=x86-64-v2 -Werror -Wall -Wextra -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations -fprofile-arcs -ftest-coverage
-fpch-preprocess -o a-TemplateTest.ii
ignoring nonexistent directory
"/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/include-fixed"
ignoring nonexistent directory
"/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:

/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13

/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/x86_64-redhat-linux

/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/backward
 /opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/include
 /usr/local/include
 /opt/rh/gcc-toolset-13/root/usr/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-D' 'BREAK' '-Werror' '-Wall' '-Wextra'
'-fno-strict-aliasing' '-fwrapv' '-fno-aggressive-loop-optimizations'
'-fprofile-arcs' '-ftest-coverage' '-o' 'a.out' '-shared-libgcc'
'-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'a-'
 /opt/rh/gcc-toolset-13/root/usr/libexec/gcc/x86_64-redhat-linux/13/cc1plus
-fpreprocessed a-TemplateTest.ii -quiet -dumpdir a- -dumpbase TemplateTest.cpp
-dumpbase-ext .cpp -mtune=generic -march=x86-64-v2 -Werror -Wall -Wextra
-version -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations
-fprofile-arcs -ftest-coverage -o a-TemplateTest.s
GNU C++17 (GCC) version 13.1.1 20230614 (Red Hat 13.1.1-4)
(x86_64-redhat-linux)
        compiled by GNU C version 13.1.1 20230614 (Red Hat 13.1.1-4), GMP
version 6.2.0, MPFR version 4.1.0-p9, MPC version 1.2.1, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 3dd233bf2ce4a586bdc966370f82782b
TemplateTest.cpp: In function ‘void __tls_init()’:
TemplateTest.cpp:22:54: error: function starts on a higher line number than it
ends [-Werror=coverage-invalid-line-number]
   22 | template <class T> thread_local std::unique_ptr<int>
Base<T>::count(nullptr);
      |                                                      ^~~~~~~
TemplateTest.cpp: In function ‘std::unique_ptr<int>&
_ZTWN4BaseI3FooE5countE()’:
TemplateTest.cpp:22:54: error: function starts on a higher line number than it
ends [-Werror=coverage-invalid-line-number]
cc1plus: all warnings being treated as errors
-----------------------------------------------------------------------


Thanks for any help you can provide,
Phil
  • [Bug c++/110715] New: Stat... obi.phil+gcc at googlemail dot com via Gcc-bugs

Reply via email to