Bug 70435 - section attribute of a function template is not honored.
Summary: section attribute of a function template is not honored.
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2016-03-29 12:38 UTC by kukyakya
Modified: 2021-12-20 12:07 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 5.3.0, 6.4.0, 7.3.0, 8.2.0, 9.0
Last reconfirmed: 2018-09-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description kukyakya 2016-03-29 12:38:41 UTC
namespace /* anonymous */
{
  [[gnu::section(".mysection")]]
  void regular_func() { }

  template <class T>
  [[gnu::section(".mysection")]]
  void template_func() { }
} // namespace /* anonymous */

void (*ptr1)() = &regular_func;
void (*ptr2)() = &template_func<int>;


In the code above the section attribute is given to both of the regular function and the function template, but the templated function is not placed in .mysection but .text.

$ g++ -std=c++14 a.cpp -c && objdump -t a.o | grep -E "regular|template"
0000000000000000 l     F .mysection	0000000000000007 _ZN12_GLOBAL__N_112regular_funcEv
0000000000000000 l     F .text	0000000000000007 _ZN12_GLOBAL__N_113template_funcIiEEvv
~/temp/c++/function_template_section $ 


I also tried it with clang and clang put the function into .mysection as I expected.


$ clang++ -std=c++14 a.cpp -c && objdump -t a.o | grep -E "regular|template"
0000000000000000 l     F .mysection	0000000000000006 _ZN12_GLOBAL__N_112regular_funcEv
0000000000000010 l     F .mysection	0000000000000006 _ZN12_GLOBAL__N_113template_funcIiEEvv
Comment 1 Armin van der Togt 2017-01-26 11:27:40 UTC
I am having the same problem with static member variables:

#include <sys/types.h>

class TestClassRegular {
public:
	static volatile const int32_t regularVar;
};
volatile const int32_t TestClassRegular::regularVar __attribute__ ((section(".eepromdata.ints"))) = 0;

template <uint32_t size, typename T>
class TestClassTemplate {
public:
	static volatile const int32_t templateVar;
};

template <uint32_t size, typename T>
volatile const int32_t TestClassTemplate<size,T>::templateVar  __attribute__ ((section(".eepromdata.ints"))) = 0;

int main() {
	int32_t blah = TestClassRegular::regularVar + TestClassTemplate<10, uint8_t>::templateVar;
	return blah;
}


 arm-none-eabi-objdump -t stm32l0-Template.elf | grep Var
200000c4  w    O .data	00000004 _ZN17TestClassTemplateILm10EhE11templateVarE
08080008 g     O .eepromdata	00000004 _ZN16TestClassRegular10regularVarE
Comment 2 Armin van der Togt 2017-04-08 13:57:50 UTC
Problem is still present in version 6.3.1
Comment 3 Matheus Izvekov 2018-08-02 06:54:05 UTC
Still an issue in gcc 8.2.0.
Comment 4 Martin Sebor 2018-09-14 19:12:52 UTC
Confirmed with the top of trunk.
Comment 5 Khalil 2018-09-25 15:22:30 UTC
Having similiar issues with ARM Embedded and Linux GCC. 
Having trouble finding a work around for this.
Here is an example code that demonstrates the issue in our particular use case:

===============================================================
// g++ -std=c++17 static.cpp -o static.exe
//
// objdump -t static.exe | grep thing
//     0000000000000740  u  O .rodata  0000000000000064 _ZZ5test0ILi5EEvvE5thing
//
// clang -std=c++14 static.cpp -o static.exe
// objdump -t static.exe  | grep thing
//     00000000004005d3 w O .log_entry 0000000000000064 _ZZ5test0ILi5EEvvE5thing

#include <cstdio>

#if __APPLE__
#define PUT_IN_SECTION(name) __attribute__((section("__text," name), used))
#else
#define PUT_IN_SECTION(name) __attribute__((section(name), used))
#endif

struct ThingType
{
  constexpr ThingType(const char * str): data{}
  {
    for(int i = 0; str[i] != '\0' && i < sizeof(data); i++)
    {
      data[i] = str[i];
    }
  }
  char data[100];
};

template <int dummy_template_parameter = 5>
void test0()
{
  PUT_IN_SECTION(".log_entry")
  static const ThingType thing("Goodbye!");
  printf("Hello, World!\n");
}

int main()
{
  test0();
  return 0;
}
===============================================================

Comment the test0 template line out, and the entry will appear in the 
appropriate section.
Comment 6 Felix Jones 2019-09-18 21:12:31 UTC
Related bug 88061

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

Minimal example for reproducing:
>  template <typename Type>
>  Type __attribute__( ( used, section( ".my_section" ) ) ) add_types( Type a, Type b ) {
>    return a + b;
>  }
>  
>  int main( int argc, char * argv[] ) {
>    return test_class<int>( s_value<3> ).add( add_types( 1, 2 ) );
>  }

Current behaviour: add_types within section .text
Desired behaviour: add_types within section .my_section

Clang trunk demonstrates the desired behaviour: https://godbolt.org/z/t8FNe0
Comment 7 Strager Neds 2019-11-06 23:09:33 UTC
I also encountered this bug. I started fixing this bug (and PR 88061): https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00348.html
Comment 8 Klaus Rudolph 2021-11-26 20:03:17 UTC
Bug still present in 11.2.1