]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: section attribute on templates [PR70435, PR88061]
authorPatrick Palka <ppalka@redhat.com>
Fri, 15 Dec 2023 15:03:31 +0000 (10:03 -0500)
committerPatrick Palka <ppalka@redhat.com>
Fri, 15 Dec 2023 15:03:31 +0000 (10:03 -0500)
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.

gcc/cp/pt.cc
gcc/testsuite/g++.dg/ext/attr-section1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-section1a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-section2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-section2a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-section2b.C [new file with mode: 0644]

index 50e6f062c85948ca159fad5ab4b263336849e377..a82d7ae93aae859607a4647a9fa110d79968741c 100644 (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)
diff --git a/gcc/testsuite/g++.dg/ext/attr-section1.C b/gcc/testsuite/g++.dg/ext/attr-section1.C
new file mode 100644 (file)
index 0000000..b8ac65b
--- /dev/null
@@ -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} } }
diff --git a/gcc/testsuite/g++.dg/ext/attr-section1a.C b/gcc/testsuite/g++.dg/ext/attr-section1a.C
new file mode 100644 (file)
index 0000000..be24be2
--- /dev/null
@@ -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} } }
diff --git a/gcc/testsuite/g++.dg/ext/attr-section2.C b/gcc/testsuite/g++.dg/ext/attr-section2.C
new file mode 100644 (file)
index 0000000..a76f43b
--- /dev/null
@@ -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} } }
diff --git a/gcc/testsuite/g++.dg/ext/attr-section2a.C b/gcc/testsuite/g++.dg/ext/attr-section2a.C
new file mode 100644 (file)
index 0000000..a0b01cd
--- /dev/null
@@ -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} } }
diff --git a/gcc/testsuite/g++.dg/ext/attr-section2b.C b/gcc/testsuite/g++.dg/ext/attr-section2b.C
new file mode 100644 (file)
index 0000000..7b8313b
--- /dev/null
@@ -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} } }