From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 791BA38AA24B; Tue, 15 Nov 2022 19:14:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 791BA38AA24B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1668539664; bh=bKfOl4hGElWhRTj5d+qhFEDMClJVTVD+cV7gakQE4a4=; h=From:To:Subject:Date:From; b=f5QV+9iWUy53hmIW/TbvFim8l+FGqdwWttzfhQG32IbBR3jPmaZN+qZq8d1PWio5F z9iELzySAYY2s87E45ZxUh6NCcv6P2T6j5NQ9PAw2y6UxCXZtlejz321EzRyAiagDs NVUF/wtFcrEUW7d7FtsIjaGVyPBor7BBfxfpgFv0= From: "cfsteefel at arista dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug lto/107708] New: LTO causes gnu::constructor functions to not be called with correct arguments if there is more than one constructor Date: Tue, 15 Nov 2022 19:14:23 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: lto X-Bugzilla-Version: 11.3.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: cfsteefel at arista dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter cc target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D107708 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 namespace { int c; char ** a; [[ gnu::constructor ]] void foo( int argc, char ** argv ) { a =3D argv; c =3D 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=3D. ./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 w= ill 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 ju= st: int c; char ** a; [[ gnu::constructor ]] void foo( int argc, char ** argv ) { a =3D argv; c =3D 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 =3D argv; | ^ lto1: note: 'argv' was declared here text.cpp:9:6: warning: 'argc' is used uninitialized [-Wuninitialized] 9 | c =3D 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=