public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
@ 2020-11-10  4:55 erstrauss at gmail dot com
  2020-11-10  8:16 ` [Bug c++/97771] " rguenth at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: erstrauss at gmail dot com @ 2020-11-10  4:55 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 97771
           Summary: gcc/g++ failed to generate proper .init_array entries
                    for local scope function, should create "axG",
                    .init_array comdat
           Product: gcc
           Version: 10.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: erstrauss at gmail dot com
  Target Milestone: ---

The the program below creates a local function inside a Local structure, and
adds the
local function address into the .init_array section in order to call that local
function at process start.

The localFunc template function is using a source_location const static
variable as template parameter.


g++ fails to place the address of the Local::init() functions inside the
.init_array.


$ cat init_array5.cpp 
#include <experimental/source_location>
#include <iostream>

using namespace std::experimental;

template<const source_location& X>
void localFunc(const char* name)
{
    static int                     count{0};
    volatile ::std::ios_base::Init dummy{};
    std::cout << "post-main-start: " << name << " " << X.file_name() << " " <<
X.line()
              << " &count: " << (void*)&count << " count: " << (++count) << " "
              << __PRETTY_FUNCTION__ << std::endl;

    struct Local
    {
        static void init()
        {
            volatile ::std::ios_base::Init dummy{};
            std::cout << "pre-main-start init from localFunc: " <<
X.file_name() << " "
                      << X.line() << " &count: " << (void*)&count
                      << " count: " << (++count) << " " << X.function_name() <<
" / " << __PRETTY_FUNCTION__
                      << std::endl;
        }
    };

    static void* volatile initp
        __attribute__((__used__, section(".init_array"))){(void*)&Local::init};
  //**** not places into .init_array.
}

#define LOCAL_FUNC(NAME)                                      \
    do                                                        \
    {                                                         \
        constexpr static auto s = source_location::current(); \
        localFunc<s>((const char*)&(NAME)[0]);                \
    } while (0)

void okFunc1() { LOCAL_FUNC("X1"); }
void okFunc2() { LOCAL_FUNC("X2"); }

int main()
{
    std::cout << "main() started" << std::endl;
    okFunc1();
    okFunc2();
    return 0;
}


==========================
output of the g++ compiled code, without the calls to the Local::init()
functions.

$ g++ -O2 -std=c++20 init_array5.cpp -o init_array5
$ ./init_array5
main() started
post-main-start: X1 init_array5.cpp 38 &count: 0x4041d8 count: 1 void
localFunc(const char*) [with const
std::experimental::fundamentals_v2::source_location& X = s]
post-main-start: X2 init_array5.cpp 39 &count: 0x4041d4 count: 1 void
localFunc(const char*) [with const
std::experimental::fundamentals_v2::source_location& X = s]


In case the same code is compiled using clang++, the pre-main local functions
are being called.

$ clang++ -O2 -std=c++20 init_array5.cpp -o init_array5
$ ./init_array5
pre-main-start init from localFunc: init_array5.cpp 38 &count: 0x4041d8 count:
1 okFunc1 / static void localFunc(const char *)::Local::init()
pre-main-start init from localFunc: init_array5.cpp 39 &count: 0x4041dc count:
1 okFunc2 / static void localFunc(const char *)::Local::init()
main() started
post-main-start: X1 init_array5.cpp 38 &count: 0x4041d8 count: 2 void
localFunc(const char *) [X = s]
post-main-start: X2 init_array5.cpp 39 &count: 0x4041dc count: 2 void
localFunc(const char *) [X = s]


g++ version information:
$ g++ --version -v
Using built-in specs.
COLLECT_AS_OPTIONS='--version'
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
g++ (GCC) 10.2.1 20201016 (Red Hat 10.2.1-6)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr
--mandir=/usr/share/man --infodir=/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 --with-linker-hash-style=gnu --enable-plugin
--enable-initfini-array --with-isl --enable-offload-targets=nvptx-none
--without-cuda-driver --enable-gnu-indirect-function --enable-cet
--with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.1 20201016 (Red Hat 10.2.1-6) (GCC) 
COLLECT_GCC_OPTIONS='--version' '-v' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/10/cc1 -quiet -v help-dummy -quiet
-dumpbase help-dummy -mtune=generic -march=x86-64 -auxbase help-dummy -version
--version -o /tmp/ccSrOtZU.s
GNU C17 (GCC) version 10.2.1 20201016 (Red Hat 10.2.1-6) (x86_64-redhat-linux)
        compiled by GNU C version 10.2.1 20201016 (Red Hat 10.2.1-6), GMP
version 6.2.0, MPFR version 4.1.0, MPC version 1.1.0, isl version
isl-0.16.1-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
COLLECT_GCC_OPTIONS='--version' '-v' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
 as -v --64 --version -o /tmp/ccPXlGcS.o /tmp/ccSrOtZU.s
GNU assembler version 2.35 (x86_64-redhat-linux) using BFD version version
2.35-14.fc33
GNU assembler version 2.35-14.fc33
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-redhat-linux'.
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/10/:/usr/libexec/gcc/x86_64-redhat-linux/10/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/10/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/10/:/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/10/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='--version' '-v' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/10/collect2 -plugin
/usr/libexec/gcc/x86_64-redhat-linux/10/liblto_plugin.so
-plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/10/lto-wrapper
-plugin-opt=-fresolution=/tmp/cc7OxEZS.res -plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id
--no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2 --version
/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/10/crtbegin.o
-L/usr/lib/gcc/x86_64-redhat-linux/10
-L/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64 -L/lib/../lib64
-L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/10/../../..
/tmp/ccPXlGcS.o -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/x86_64-redhat-linux/10/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/crtn.o
collect2 version 10.2.1 20201016 (Red Hat 10.2.1-6)
/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/10/liblto_plugin.so
-plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/10/lto-wrapper
-plugin-opt=-fresolution=/tmp/cc7OxEZS.res -plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id
--no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2 --version
/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/10/crtbegin.o
-L/usr/lib/gcc/x86_64-redhat-linux/10
-L/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64 -L/lib/../lib64
-L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/10/../../..
/tmp/ccPXlGcS.o -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/x86_64-redhat-linux/10/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/10/../../../../lib64/crtn.o
GNU ld version 2.35-14.fc33
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
COLLECT_GCC_OPTIONS='--version' '-v' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
@ 2020-11-10  8:16 ` rguenth at gcc dot gnu.org
  2020-11-10 13:27 ` erstrauss at gmail dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-11-10  8:16 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think the GCC "portable" way of doing this is to attach the constructor
attribute to Local::init.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
  2020-11-10  8:16 ` [Bug c++/97771] " rguenth at gcc dot gnu.org
@ 2020-11-10 13:27 ` erstrauss at gmail dot com
  2020-11-10 14:31 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: erstrauss at gmail dot com @ 2020-11-10 13:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Erez Strauss <erstrauss at gmail dot com> ---
Thanks, I tried, it fails with:

$ g++ -O2 -std=c++20 init_array5c.cpp -o init_array5c
init_array5c.cpp: In function ‘void localFunc(const char*)’:
init_array5c.cpp:17:55: warning: ‘constructor’ attribute ignored [-Wattributes]
   17 |         static void init() __attribute__((constructor))
      |                                                       ^
===========================
$ ./init_array5c
main() started
post-main-start: X1 init_array5c.cpp 37 &count: 0x4041d4 count: 1 void
localFunc(const char*) [with const
std::experimental::fundamentals_v2::source_location& X = s]
post-main-start: X2 init_array5c.cpp 38 &count: 0x4041dc count: 1 void
localFunc(const char*) [with const
std::experimental::fundamentals_v2::source_location& X = s]
===========================

clang++ accepts correctly the attribute:
$ clang++ -O2 -std=c++20 init_array5c.cpp -o init_array5c
===========================
$ ./init_array5c
pre-main-start init from localFunc: init_array5c.cpp 37 &count: 0x4041d8 count:
1 okFunc1 / static void localFunc(const char *)::Local::init()
pre-main-start init from localFunc: init_array5c.cpp 38 &count: 0x4041dc count:
1 okFunc2 / static void localFunc(const char *)::Local::init()
main() started
post-main-start: X1 init_array5c.cpp 37 &count: 0x4041d8 count: 2 void
localFunc(const char *) [X = s]
post-main-start: X2 init_array5c.cpp 38 &count: 0x4041dc count: 2 void
localFunc(const char *) [X = s]

===========================

$ cat init_array5c.cpp
#include <experimental/source_location>
#include <iostream>

using namespace std::experimental;

template<const source_location& X>
void localFunc(const char* name)
{
    static int                     count{0};
    volatile ::std::ios_base::Init dummy{};
    std::cout << "post-main-start: " << name << " " << X.file_name() << " " <<
X.line()
              << " &count: " << (void*)&count << " count: " << (++count) << " "
              << __PRETTY_FUNCTION__ << std::endl;

    struct Local
    {
        static void init() __attribute__((constructor))
        {
            volatile ::std::ios_base::Init dummy{};
            std::cout << "pre-main-start init from localFunc: " <<
X.file_name() << " "
                      << X.line() << " &count: " << (void*)&count
                      << " count: " << (++count) << " " << X.function_name() <<
" / " << __PRETTY_FUNCTION__
                      << std::endl;
        }
    };

    //static void* volatile initp __attribute__((__used__,
section(".init_array"))){(void*)&Local::init};
}

#define LOCAL_FUNC(NAME)                                      \
    do                                                        \
    {                                                         \
        constexpr static auto s = source_location::current(); \
        localFunc<s>((const char*)&(NAME)[0]);                \
    } while (0)

void okFunc1() { LOCAL_FUNC("X1"); }
inline void okFunc2() { LOCAL_FUNC("X2"); }

int main()
{
    std::cout << "main() started" << std::endl;
    okFunc1();
    okFunc2();
    return 0;
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
  2020-11-10  8:16 ` [Bug c++/97771] " rguenth at gcc dot gnu.org
  2020-11-10 13:27 ` erstrauss at gmail dot com
@ 2020-11-10 14:31 ` jakub at gcc dot gnu.org
  2020-11-10 14:43 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-10 14:31 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
What you are doing is certainly wrong.  .init_array section needs to be
@init_array,
there is no way to create initialized variables in anything but @progbits.
The section attribute doesn't have any list of magic sections that should be
treated differently from anything else.
constructor attribute indeed is only allowed on file-scope functions.
Why don't you use inline asm?
I'd suggest
        __asm (".section .init_array, \"aw\",%%init_array; .balign %P0;
.%P0byte %P1; .previous" : : "i" (sizeof (void *)), "g" ((void
*)&Local::init));
instead of your initp declaration.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
                   ` (2 preceding siblings ...)
  2020-11-10 14:31 ` jakub at gcc dot gnu.org
@ 2020-11-10 14:43 ` jakub at gcc dot gnu.org
  2020-11-11  2:29 ` erstrauss at gmail dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-10 14:43 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
That is about the assembler warning (which isn't fatal though); for the uses in
inline functions or templates anothing thing is that the comdat sections from
comdat take priority over the section attribute.
Now, when assembler doesn't support comdat groups, there is really no way
around it, section attribute has to be ignored and one needs to use
.gnu.linkonce.* etc. sections, because otherwise it wouldn't act as comdat.
With comdat groups, we could use the section name from the section attribute
and just put it into the comdat group, but don't do that.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
                   ` (3 preceding siblings ...)
  2020-11-10 14:43 ` jakub at gcc dot gnu.org
@ 2020-11-11  2:29 ` erstrauss at gmail dot com
  2021-08-17  7:47 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: erstrauss at gmail dot com @ 2020-11-11  2:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Erez Strauss <erstrauss at gmail dot com> ---
Yes, thanks, the asm() works - but if it can be expressed in C++, why add the
dependency on assembly?

1. attribute constructor - fails to compile
2. placing the address into the .init_array fails to generate the proper code.
3. assembly is required for gcc, but not for clang.

I minimized the program by avoiding any include files, having three different
macros for the different options.
I would expect that gcc will handle correctly the first two options, as other
compilers do.

See https://godbolt.org/z/Mr1794  - for the three compilers: gcc clang icc

========================================
$ cat init_array_minimized.cpp

extern "C" int           write(int, const char *, long);
extern "C" unsigned long strlen(const char *);
extern "C" int           snprintf(char *, unsigned long, const char *, ...);

#define SIMPLE_LOCAL_FUNC_INIT_ARRAY()                                         
     \
    do                                                                         
     \
    {                                                                          
     \
        struct Local                                                           
     \
        {                                                                      
     \
            static void init()                                                 
     \
            {                                                                  
     \
                char buffer[256];                                              
     \
                snprintf(buffer, sizeof(buffer), "%p: %s:%d: %s\n",
(void*)&init, __FILE__, __LINE__,  \
                         __PRETTY_FUNCTION__);                                 
     \
                write(1, buffer, strlen(buffer));                              
     \
            }                                                                  
     \
        };                                                                     
     \
        static void *volatile initp __attribute__((__used__,
section(".init_array"))){(void *)&Local::init}; \
    } while (0)

#define SIMPLE_LOCAL_FUNC_CONSTRUCTOR()                                        
     \
    do                                                                         
     \
    {                                                                          
     \
        struct Local                                                           
     \
        {                                                                      
     \
            static void init() __attribute__((constructor))                    
     \
            {                                                                  
     \
                char buffer[256];                                              
     \
                snprintf(buffer, sizeof(buffer), "%p: %s:%d: %s\n",
(void*)&init, __FILE__, __LINE__,  \
                         __PRETTY_FUNCTION__);                                 
     \
                write(1, buffer, strlen(buffer));                              
     \
            }                                                                  
     \
        };                                                                     
     \
    } while (0)

#define SIMPLE_LOCAL_FUNC_INIT_ASM()                                           
     \
    do                                                                         
     \
    {                                                                          
     \
        struct Local                                                           
     \
        {                                                                      
     \
            static void init()                                                 
     \
            {                                                                  
     \
                char buffer[256];                                              
     \
                snprintf(buffer, sizeof(buffer), "%p: %s:%d: %s\n",
(void*)&init, __FILE__, __LINE__,  \
                         __PRETTY_FUNCTION__);                                 
     \
                write(1, buffer, strlen(buffer));                              
     \
            }                                                                  
     \
        };                                                                     
     \
  __asm (".section .init_array, \"aw\",%%init_array; .balign %P0; .%P0byte %P1;
.previous" : : "i" (sizeof (void *)), "g" ((void*)&Local::init)); \
    } while (0)




//#define LOCAL_INIT_FUNC() SIMPLE_LOCAL_FUNC_INIT_ARRAY()
//#define LOCAL_INIT_FUNC() SIMPLE_LOCAL_FUNC_CONSTRUCTOR()
#define LOCAL_INIT_FUNC() SIMPLE_LOCAL_FUNC_INIT_ASM()



void funcA() {
        LOCAL_INIT_FUNC();
        LOCAL_INIT_FUNC();
}

inline void funcB() { LOCAL_INIT_FUNC(); }

template<int> void funcT(int) { LOCAL_INIT_FUNC(); }

int main()
{
    write(1, "main\n", 5);
    funcA();
    funcB();
    funcT<0>(0);
    funcT<1>(0);
    return 0;
}
==================================

$ g++ -std=c++20  -O2 -fverbose-asm --save-temps -o init_array_minimized
init_array_minimized.cpp
$ ./init_array_minimized 
0x4011e0: init_array_minimized.cpp:63: static void funcA()::Local::init()
0x401180: init_array_minimized.cpp:64: static void funcA()::Local::init()
0x401250: init_array_minimized.cpp:67: static void funcB()::Local::init()
0x4012b0: init_array_minimized.cpp:69: static void funcT(int)::Local::init()
[with int <anonymous> = 0]
0x401310: init_array_minimized.cpp:69: static void funcT(int)::Local::init()
[with int <anonymous> = 1]
main

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
                   ` (4 preceding siblings ...)
  2020-11-11  2:29 ` erstrauss at gmail dot com
@ 2021-08-17  7:47 ` pinskia at gcc dot gnu.org
  2021-08-29  2:45 ` erstrauss at gmail dot com
  2021-08-29  3:12 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-17  7:47 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |DUPLICATE

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup of bug 88061.  Though I suspect both PR 88061 and PR 70435 are invalid.

*** This bug has been marked as a duplicate of bug 88061 ***

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
                   ` (5 preceding siblings ...)
  2021-08-17  7:47 ` pinskia at gcc dot gnu.org
@ 2021-08-29  2:45 ` erstrauss at gmail dot com
  2021-08-29  3:12 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: erstrauss at gmail dot com @ 2021-08-29  2:45 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Erez Strauss <erstrauss at gmail dot com> ---
Hi Andrew,

Here is a very simple test program, under clang++ its output is 3, as expected.
Its output is 2 in case of g++ 11.2.1 20210728 (Red Hat 11.2.1-1)

#include <iostream>

static int X;

typedef void (*funcP)();

static funcP g_init_func [[gnu::used, gnu::section(".init_array")]] {
[]()->void{++X;} };

void funcA() {
    static funcP init_func [[gnu::used, gnu::section(".init_array")]] {
[]()->void{++X;} };
}

template<typename T>
void funcB() {
    static funcP init_func [[gnu::used, gnu::section(".init_array")]] {
[]()->void{++X;} };
}

void testT() {
    funcB<int>();
}


int main()
{
    std::cout << X << std::endl;
    testT();
    return 0;
}


Please test the above to generate 3 as output with g++.
Thanks,
Erez

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat
  2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
                   ` (6 preceding siblings ...)
  2021-08-29  2:45 ` erstrauss at gmail dot com
@ 2021-08-29  3:12 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-29  3:12 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Erez Strauss from comment #7)
> Hi Andrew,
> 
> Here is a very simple test program, under clang++ its output is 3, as
> expected.

Right I already mentioned this is a dup of still opened bug 88061 .  The
problem is clang might be emitting really really broken assembly and only can
be resolved at link time.

Take:
template<typename T>
void funcB() {
    static funcP init_func [[gnu::used, gnu::section(".init_array")]] {
[]()->void{++X;} };
}

----- CUT -----
funcB<int>::init_func has to be the same between TUs and that means emiting it
in the comdat section.  In fact the use of X here might actually cause this
code to be full on invalid anyways.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-08-29  3:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-10  4:55 [Bug c++/97771] New: gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat erstrauss at gmail dot com
2020-11-10  8:16 ` [Bug c++/97771] " rguenth at gcc dot gnu.org
2020-11-10 13:27 ` erstrauss at gmail dot com
2020-11-10 14:31 ` jakub at gcc dot gnu.org
2020-11-10 14:43 ` jakub at gcc dot gnu.org
2020-11-11  2:29 ` erstrauss at gmail dot com
2021-08-17  7:47 ` pinskia at gcc dot gnu.org
2021-08-29  2:45 ` erstrauss at gmail dot com
2021-08-29  3:12 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).