From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 718FC385840B; Thu, 4 Nov 2021 13:48:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 718FC385840B From: "iains at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug ipa/103080] New: LTO alters the ordering of static constructors/destructors in pass_ipa_cdtor_merge. Date: Thu, 04 Nov 2021 13:48:28 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: ipa X-Bugzilla-Version: 12.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: iains at gcc dot gnu.org 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 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Nov 2021 13:48:28 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D103080 Bug ID: 103080 Summary: LTO alters the ordering of static constructors/destructors in pass_ipa_cdtor_merge. Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: iains at gcc dot gnu.org CC: marxin at gcc dot gnu.org Target Milestone: --- consider the following : -------- #include /* Define USE_PRIO to to test that.*/ #ifdef USE_PRIO #define PRIO_CTOR constructor(12345) #define PRIO_DTOR destructor(12345) #else #define PRIO_CTOR constructor #define PRIO_DTOR destructor #endif __attribute__((constructor)) static void startup () { fprintf(stderr, "startup\n"); } __attribute__((destructor)) static void shutdown () { fprintf(stderr, "shutdown\n"); } __attribute__((PRIO_CTOR)) static void startup1 () { fprintf(stderr, "startup1\n"); } __attribute__((PRIO_CTOR)) static void startup2 () { fprintf(stderr, "startup2\n"); } __attribute__((PRIO_DTOR)) static void shutdown1 () { fprintf(stderr, "shutdown1\n"); } __attribute__((destructor)) static void shutdown2 () { fprintf(stderr, "shutdown2\n"); } int main () { printf ("42\n"); return 0; } =3D=3D=3D=3D This initial output is (to the best of my knowledge, although we do not document it well enough) the correct behaviour. Essentially, we execute the static constructors in order of declaration and the destructors in the reve= rse order. This is the most reasonable ordering from the user's perspective and more-or-less follows what C++ does (although the static DTORs are not tied = to their CTORs - they *can* be placed together in the source to make it readab= le). $ ./gcc/xgcc -Bgcc ~/ctor-dtor.c -o ct=20 $ ./ct startup startup1 startup2 42 shutdown2 shutdown1 shutdown ----- $ ./gcc/xgcc -Bgcc ~/ctor-dtor.c -o ct -flto $ ./ct startup2 startup1 startup 42 shutdown shutdown1 shutdown2 This is not (IMO at least) correct - at the very least the program behaviour will be different with/without LTO. I suspect that the logic is inverted in ipa.c:compare_ctor / compare_dtor.= =20 There is a comment that this is intended to make it more likely that library CTORs will run early - but ISTM that if that is needed then an alternate mechanism must be used. =3D=3D=3D=3D=3D=3D=3D similar issues when priority is in use NOTE that the different DTOR ordering *is* intentional as can be seen from = the source above. $ ./gcc/xgcc -Bgcc ~/ctor-dtor.c -o ct -DUSE_PRIO $ ./ct startup1 startup2 startup 42 shutdown2 shutdown shutdown1 --- $ ./gcc/xgcc -Bgcc ~/ctor-dtor.c -o ct -DUSE_PRIO -flto $ ./ct startup2 startup1 startup 42 shutdown shutdown2 shutdown1 =3D=3D=3D=3D=3D=3D=