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

            Bug ID: 105876
           Summary: use of -flto with g++ changes global extern const
                    std::string initialization in unexpected manner
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: lto
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kevin.b.hendricks at icloud dot com
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

Created attachment 53101
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53101&action=edit
text copy of the above for extracting source code

Use of -flto with g++ causes extern const std::string variable to be
initialized after a static const class variable.

This behaviour is not present when -flto is not used.  This same simple test
case works with and without -flto with clang++.

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit
--enable-cet=auto --enable-checking=release --enable-clocale=gnu
--enable-default-pie --enable-default-ssp --enable-gnu-indirect-function
--enable-gnu-unique-object --enable-linker-build-id --enable-lto
--enable-multilib --enable-plugin --enable-shared --enable-threads=posix
--disable-libssp --disable-libstdcxx-pch --disable-werror
--with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.0 (GCC) 

uname -a
Linux kevin-virtualbox 5.15.41-1-MANJARO #1 SMP PREEMPT Wed May 18 09:20:01 UTC
2022 x86_64 GNU/Linux


Simple Test Case Sources
-----------------

--- sg_constants.h ---
  #include <string>
  extern const std::string MAIN_EXTERN_CONST_STRING;

--- sg_test.h ---
  class sg_test
  {
  public:
    sg_test();
  };


--- main.cpp ---
  #include <iostream>
  #include <string>

  #include "sg_constants.h"
  #include "sg_test.h"

  const std::string MAIN_EXTERN_CONST_STRING= "a_literal_string_value";

  int main(int argc, char *argv[])
  {
    (void) argc; (void) argv;
    std::cout << "In main MAIN_EXTERN_CONST_STRING is: " << "'" <<
MAIN_EXTERN_CONST_STRING << "'" << std::endl;
    sg_test * psg = new sg_test();
    (void) psg;
    return 0;
  }


--- sg_test.cpp ---
  #include <iostream>
  #include "sg_constants.h"
  #include "sg_test.h"

  static const std::string TEST_STATIC_CONST_STRING = MAIN_EXTERN_CONST_STRING;

  sg_test::sg_test()
  {
    std::cout << "In sg_test object TEST_STATIC_CONST_STRING is: " << "'" <<
TEST_STATIC_CONST_STRING << "'" << std::endl;
    std::cout << "In sg_test object MAIN_EXTERN_CONST_STRING is: " << "'" <<
MAIN_EXTERN_CONST_STRING << "'" << std::endl;
  }



$ cat buildme.sh
g++ -I. -g -O2 -Wall -Wextra -c sg_test.cpp
g++ -I. -O2 -Wall -Wextra -c main.cpp
g++ -o no_lto_test *.o
rm -f *.o

g++ -I. -g -O2 -flto=auto -Wall -Wextra -c sg_test.cpp
g++ -I. -g -O2 -flto=auto -Wall -Wextra -c main.cpp
g++ -flto=auto -o lto_test *.o

echo "Without lto"
./no_lto_test
echo " "
echo "With lto"
./lto_test


$ ./buildme.sh

Without lto
In main MAIN_EXTERN_CONST_STRING is: 'a_literal_string_value'
In sg_test object TEST_STATIC_CONST_STRING is: 'a_literal_string_value'
In sg_test object MAIN_EXTERN_CONST_STRING is: 'a_literal_string_value'

With lto
In main MAIN_EXTERN_CONST_STRING is: 'a_literal_string_value'
In sg_test object TEST_STATIC_CONST_STRING is: ''
In sg_test object MAIN_EXTERN_CONST_STRING is: 'a_literal_string_value'

Reply via email to