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

2021-08-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

--- Comment #8 from Andrew Pinski  ---
(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
void funcB() {
static funcP init_func [[gnu::used, gnu::section(".init_array")]] {
[]()->void{++X;} };
}

- CUT -
funcB::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.

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

2021-08-28 Thread erstrauss at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

--- Comment #7 from Erez Strauss  ---
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 

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
void funcB() {
static funcP init_func [[gnu::used, gnu::section(".init_array")]] {
[]()->void{++X;} };
}

void testT() {
funcB();
}


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


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

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

2021-08-17 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

Andrew Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #6 from Andrew Pinski  ---
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 ***

[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 Thread erstrauss at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

--- Comment #5 from Erez Strauss  ---
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 void funcT(int) { LOCAL_INIT_FUN

[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 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jason at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek  ---
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.

[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 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek  ---
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.

[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 Thread erstrauss at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

--- Comment #2 from Erez Strauss  ---
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 
#include 

using namespace std::experimental;

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

[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 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97771

Richard Biener  changed:

   What|Removed |Added

   Keywords||wrong-code

--- Comment #1 from Richard Biener  ---
I think the GCC "portable" way of doing this is to attach the constructor
attribute to Local::init.