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

            Bug ID: 123405
           Summary: LTO removes explicit section attribute from localized
                    COMDAT symbols
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: loki at loki dot codes
  Target Milestone: ---

When a COMDAT symbol with an explicit [[gnu::section()]] attribute is localized
during LTO's visibility pass, the section is incorrectly removed.

In gcc/ipa-visibility.cc, localize_node() unconditionally clears the
section for COMDAT symbols:

if (DECL_COMDAT (node->decl) && !node->alias)
    node->set_section (NULL);

This does not check implicit_section, so user-specified sections are lost.

ICF already handles this case correctly:

if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
        || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))


Reproducer:

Template class with two static member functions, both with
[[gnu::section(".root_section")]]:

- Function A: referenced externally (e.g., vector table)
    -> stays externally_visible -> section preserved
- Function B: only referenced internally
    -> localized -> section lost

Expected: Both functions land in .root_section, OR a warning is emitted
        indicating that the section attribute will be ignored.
Actual:   Only the externally-visible function keeps the section;
        the localized function ends up in .text. No warning is issued.


Proposed fix:

if (DECL_COMDAT (node->decl) && !node->alias && node->implicit_section)
    node->set_section (NULL);


Notes:

The same issue was discussed in PR 65262 and closed as WONTFIX. The reasoning,
as I understand it, is that LTO is free to privatize symbols. That may be
correct, but in this case a GCC feature does not work as documented:

- [[gnu::section()]] is a documented feature of GCC
- No limitations are documented for the section attribute
- No limitations regarding attributes are documented for LTO

Additionally, the [[gnu::noinline]] attribute has no effect on this behavior.
Only applying [[gnu::noipa]] prevents explicit sections from being lost, but
this has other implications: even functions residing in the same section can
no longer be optimized at link time.

Reply via email to