Bug 88061 - section attributes of variable templates are ignored
Summary: section attributes of variable templates are ignored
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.3.0
: P3 normal
Target Milestone: 14.0
Assignee: Patrick Palka
URL:
Keywords: diagnostic
: 97771 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-11-16 15:41 UTC by Henrik
Modified: 2023-12-16 17:58 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-11-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Henrik 2018-11-16 15:41:40 UTC
When providing a variable template with a section attribute its instantiations do not appear in the specified section:

==========================================================

template<unsigned x>
[[gnu::section(".my_data")]] const unsigned g_my_data {x};

template const unsigned g_my_data<0xf0f0f0f0>;

==========================================================

$ g++-7 -c main.cpp -o main.o -std=c++14
$ objdump main.o --full-content

  main.o:     Format elf64-x86-64

  Section .group:
   0000 01000000 05000000                    ........        
  Section .rodata._Z9g_my_dataILj4042322160EE:
   0000 f0f0f0f0                             ....            
  Section .comment:
   0000 00474343 3a202855 62756e74 7520372e  .GCC: (Ubuntu 7.
   0010 332e302d 32337562 756e7475 327e3136  3.0-23ubuntu2~16
   0020 2e30342e 796f726b 30292037 2e332e30  .04.york0) 7.3.0
   0030 00                                   .
Comment 1 Richard Biener 2018-11-19 09:07:36 UTC
I'm not sure such request can be honored given the section has to be comdat
which essentially means it has to have it's own section for each
different instantiation.  Thus, would we reject

template<unsigned x>
[[gnu::section(".my_data")]] const unsigned g_my_data {x};

template const unsigned g_my_data<0xf0f0f0f0>;
template const unsigned g_my_data<0xf0f0f0f1>;

as invalid with an error?  Or somehow take .my_data as prefix and mangle
it appropriately, assigning it COMDAT?

Some things do not make very much sense for C++...
Comment 2 Felix Jones 2019-09-18 21:12:33 UTC
Related bug 70435

Here's a demonstration of the issue with GCC trunk x86-64 on godbolt: https://godbolt.org/z/9GFWZR

Minimal example for reproducing:
>  template<int x>
>  __attribute__( ( used, section( ".my_section" ) ) ) const int s_value { x };
>  
>  int main( int argc, char * argv[] ) {
>    return s_value<3>;
>  }

Current behaviour: s_value within section .rodata
Desired behaviour: s_value within section .my_section

Clang trunk demonstrates the desired behaviour: https://godbolt.org/z/t8FNe0
Comment 3 Strager Neds 2019-11-06 23:09:01 UTC
I also encountered this bug. I started fixing this bug (and PR 70435): https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00348.html
Comment 4 Andrew Pinski 2021-08-17 07:47:34 UTC
*** Bug 97771 has been marked as a duplicate of this bug. ***
Comment 5 Barry Revzin 2022-03-08 17:31:17 UTC
(In reply to Richard Biener from comment #1)
> Some things do not make very much sense for C++...

I disagree. This definitely makes sense for C++ and it is disappointing that it doesn't work. 

For instance, this works:

[[gnu::used, gnu::section(".my_data")]] inline int data_int;
[[gnu::used, gnu::section(".my_data")]] inline double data_double;

int& get() {
    return data_int;
}

The C++ analogue, necessary for contexts where I may not be able to spell the type in advance, would be this (or a static data member of a class template, same thing):

template <typename T>
[[gnu::used, gnu::section(".my_data")]] inline T data{};

int& get() {
    return data<int>;
}

Except the latter puts data<int> into .bss.data<int>, while the former puts it into .my_data. clang respects the section attribute (https://godbolt.org/z/7137EbxsW), gcc does not (https://godbolt.org/z/548YKjhzn).
Comment 6 Barry Revzin 2023-04-06 16:32:39 UTC
Any action on this one?

A workaround right now is to change code that would ideally look like (which is pretty clean in my opinion):

template <typename T>
void foo() {
    [[gnu::section(".meow")]] static int value = 0;
}

to code that looks like:

template <typename T>
void foo() {
    static int PUT_IN_MEOW_value = 0;
}

and add a linker script that moves these variables over:

.meow : {
KEEP(*(SORT(.*PUT_IN_MEOW_*)))
}

But this is, to put it mildly, less than ideal.
Comment 7 Milan Svoboda 2023-04-20 08:39:46 UTC
template <typename T>
static void foo() {
    static int PUT_IN_MEOW_value = 0;
}


When the template function is static, this workaround with linker doesn't work.
Comment 8 Milan Svoboda 2023-04-20 09:59:54 UTC
Well, additional workaround is to use -fdata-sections. Then the workaround with the linker script works also for the templated static functions and for functions (templated, static) in anonymous namespace (which is another occurrence of this bug).
Comment 9 GCC Commits 2023-12-15 15:04:30 UTC
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>:

https://gcc.gnu.org/g:ea7bebff7cc5a5eb780a6ca646cb77cad1b625d6

commit r14-6595-gea7bebff7cc5a5eb780a6ca646cb77cad1b625d6
Author: Patrick Palka <ppalka@redhat.com>
Date:   Fri Dec 15 10:03:31 2023 -0500

    c++: section attribute on templates [PR70435, PR88061]
    
    The section attribute currently has no effect on templates because the
    call to set_decl_section_name only happens at parse time (on the
    dependent decl) and not also at instantiation time.  This patch fixes
    this by propagating the section name from the template to the
    instantiation.
    
            PR c++/70435
            PR c++/88061
    
    gcc/cp/ChangeLog:
    
            * pt.cc (tsubst_function_decl): Propagate DECL_SECTION_NAME
            via set_decl_section_name.
            (tsubst_decl) <case VAR_DECL>: Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/ext/attr-section1.C: New test.
            * g++.dg/ext/attr-section1a.C: New test.
            * g++.dg/ext/attr-section2.C: New test.
            * g++.dg/ext/attr-section2a.C: New test.
            * g++.dg/ext/attr-section2b.C: New test.
Comment 10 Patrick Palka 2023-12-16 17:17:08 UTC
Fixed for GCC 14
Comment 11 Patrick Palka 2023-12-16 17:58:52 UTC
N.B. that commit just naively fixes the attribute propagation issue which seems to make at least simple examples work as expected.  The question of section + comdat handling could IIUC be demonstrated using non-template inline functions/variables as well and so is really an orthogonal issue I think?