public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug lto/107708] New: LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor
@ 2022-11-15 19:14 cfsteefel at arista dot com
  2022-11-15 19:24 ` [Bug lto/107708] " pinskia at gcc dot gnu.org
  2022-11-15 19:45 ` cfsteefel at arista dot com
  0 siblings, 2 replies; 3+ messages in thread
From: cfsteefel at arista dot com @ 2022-11-15 19:14 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 107708
           Summary: LTO causes gnu::constructor functions to not be called
                    with correct arguments if there is more than one
                    constructor
           Product: gcc
           Version: 11.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: lto
          Assignee: unassigned at gcc dot gnu.org
          Reporter: cfsteefel at arista dot com
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

When a function is marked with the constructor attribute, if there is more than
one function marked with the constructor attribute, the function's arguments
are not passed when LTO inlines the function into DT_INIT_ARRAY. If LTO is
disabled, the function will instead be passed argc, argv, and envp by glibc
(other libc implementation may or may not pass anything).

See the following code:
#include <iostream>
namespace {
int c;
char ** a;
[[ gnu::constructor ]]
void foo( int argc, char ** argv ) {
   a = argv;
   c = argc;
}

[[ gnu::constructor ]]
void bar( int argc, char ** argv ) {
   asm( "" );
}
}

int main() {
   std::cerr << "argc: " << c << std::endl;
   std::cerr << std::hex << a << std::endl;

   return 0;
}


When compiled and run as:
> g++ text.cpp -g -shared -o libMain.so -fPIC -O2 -flto -Wall -Wextra
> g++ libMain.so
> LD_LIBRARY_PATH=. ./a.out 4 1 2 4
A sample output is:
argc: -638171435
0x7f20366efdd0

(the use of cerr is only meaningful for actually seeing output, and is not
needed to reproduce the error)

Using a specific and unique priority for the `gnu::constructor` attribute will
lead to the arguments being passed correctly, and argc will end up correct.

If the function is instead not defined inside an anonymous namespace, as just:

int c;
char ** a;
[[ gnu::constructor ]]
void foo( int argc, char ** argv ) {
   a = argv;
   c = argc;
}
g++ instead reports the error (using -Wall -Wextra):
In function '_sub_I_65535_0':
text.cpp:8:6: warning: 'argv' is used uninitialized [-Wuninitialized]
    8 |    a = argv;
      |      ^
lto1: note: 'argv' was declared here
text.cpp:9:6: warning: 'argc' is used uninitialized [-Wuninitialized]
    9 |    c = argc;
      |      ^
lto1: note: 'argc' was declared here

Using a unique constructor priority again will disable that warning.

g++ (GCC) 11.3.1 20220421 (Red Hat 11.3.1-2)
glibc 2.34

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

* [Bug lto/107708] LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor
  2022-11-15 19:14 [Bug lto/107708] New: LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor cfsteefel at arista dot com
@ 2022-11-15 19:24 ` pinskia at gcc dot gnu.org
  2022-11-15 19:45 ` cfsteefel at arista dot com
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-11-15 19:24 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The argument passing here is not defined at all.
Yes glibc does it for ones used inside DT_INIT_ARRAY but that does mean it will
always work.

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

* [Bug lto/107708] LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor
  2022-11-15 19:14 [Bug lto/107708] New: LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor cfsteefel at arista dot com
  2022-11-15 19:24 ` [Bug lto/107708] " pinskia at gcc dot gnu.org
@ 2022-11-15 19:45 ` cfsteefel at arista dot com
  1 sibling, 0 replies; 3+ messages in thread
From: cfsteefel at arista dot com @ 2022-11-15 19:45 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Christoph Steefel <cfsteefel at arista dot com> ---
Ok. If passing arguments to a constructor function is explicitly undefined, and
gcc is willing to optimize based on that, should it be documented in the
constructor attribute docs?

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

end of thread, other threads:[~2022-11-15 19:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-15 19:14 [Bug lto/107708] New: LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor cfsteefel at arista dot com
2022-11-15 19:24 ` [Bug lto/107708] " pinskia at gcc dot gnu.org
2022-11-15 19:45 ` cfsteefel at arista dot com

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).