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.
This commit is contained in:
Patrick Palka 2023-12-15 10:03:31 -05:00
parent 46984fa259
commit ea7bebff7c
6 changed files with 59 additions and 0 deletions

View file

@ -14607,6 +14607,8 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
= remove_attribute ("visibility", DECL_ATTRIBUTES (r));
}
determine_visibility (r);
if (DECL_SECTION_NAME (t))
set_decl_section_name (r, t);
if (DECL_DEFAULTED_OUTSIDE_CLASS_P (r)
&& !processing_template_decl)
defaulted_late_check (r);
@ -15423,6 +15425,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain,
= remove_attribute ("visibility", DECL_ATTRIBUTES (r));
}
determine_visibility (r);
if ((!local_p || TREE_STATIC (t)) && DECL_SECTION_NAME (t))
set_decl_section_name (r, t);
}
if (!local_p)

View file

@ -0,0 +1,9 @@
// PR c++/70435
// { dg-do compile { target { c++11 && named_sections } } }
template<class T>
[[gnu::section(".foo")]] void fun() { }
template void fun<int>();
// { dg-final { scan-assembler {.section[ \t]+.foo} } }

View file

@ -0,0 +1,11 @@
// PR c++/70435
// { dg-do compile { target { c++11 && named_sections } } }
template<class T>
struct A {
[[gnu::section(".foo")]] void fun() { }
};
template struct A<int>;
// { dg-final { scan-assembler {.section[ \t]+.foo} } }

View file

@ -0,0 +1,9 @@
// PR c++/88061
// { dg-do compile { target { c++14 && named_sections } } }
template<class T>
[[gnu::section(".foo")]] int var = 42;
template int var<int>;
// { dg-final { scan-assembler {.section[ \t]+.foo} } }

View file

@ -0,0 +1,14 @@
// PR c++/88061
// { dg-do compile { target { c++11 && named_sections } } }
template<class T>
struct A {
[[gnu::section(".foo")]] static int var;
};
template<class T>
int A<T>::var = 42;
template struct A<int>;
// { dg-final { scan-assembler {.section[ \t]+.foo} } }

View file

@ -0,0 +1,12 @@
// PR c++/88061
// { dg-do compile { target { c++11 && named_sections } } }
template<class T>
int* fun() {
[[gnu::section(".foo")]] static int var;
return &var;
};
template int* fun<int>();
// { dg-final { scan-assembler {.section[ \t]+.foo} } }