[Bug c++/97771] gcc/g++ failed to generate proper .init_array entries for local scope function, should create "axG", .init_array comdat

erstrauss at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Nov 10 13:27:46 GMT 2020


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;
}


More information about the Gcc-bugs mailing list