From 7226f825db049517b64442a40a6387513febb8f9 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 21 Dec 2023 13:53:43 -0500 Subject: [PATCH] c++: visibility wrt template and ptrmem targs [PR70413] When constraining the visibility of an instantiation, we weren't properly considering the visibility of PTRMEM_CST and TEMPLATE_DECL template arguments. This patch fixes this. It turns out we don't maintain the relevant visibility flags for alias templates (e.g. TREE_PUBLIC is never set), so continue to ignore alias template template arguments for now. PR c++/70413 PR c++/107906 gcc/cp/ChangeLog: * decl2.cc (min_vis_expr_r): Handle PTRMEM_CST and TEMPLATE_DECL other than those for alias templates. gcc/testsuite/ChangeLog: * g++.dg/template/linkage2.C: New test. * g++.dg/template/linkage3.C: New test. * g++.dg/template/linkage4.C: New test. * g++.dg/template/linkage4a.C: New test. --- gcc/cp/decl2.cc | 22 ++++++++++++++++++---- gcc/testsuite/g++.dg/template/linkage2.C | 13 +++++++++++++ gcc/testsuite/g++.dg/template/linkage3.C | 17 +++++++++++++++++ gcc/testsuite/g++.dg/template/linkage4.C | 16 ++++++++++++++++ gcc/testsuite/g++.dg/template/linkage4a.C | 14 ++++++++++++++ 5 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/linkage2.C create mode 100644 gcc/testsuite/g++.dg/template/linkage3.C create mode 100644 gcc/testsuite/g++.dg/template/linkage4.C create mode 100644 gcc/testsuite/g++.dg/template/linkage4a.C diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 0850d3f5bce..4777ceb8af7 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2655,7 +2655,10 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data) int *vis_p = (int *)data; int tpvis = VISIBILITY_DEFAULT; - switch (TREE_CODE (*tp)) + tree t = *tp; + if (TREE_CODE (t) == PTRMEM_CST) + t = PTRMEM_CST_MEMBER (t); + switch (TREE_CODE (t)) { case CAST_EXPR: case IMPLICIT_CONV_EXPR: @@ -2666,15 +2669,26 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data) case NEW_EXPR: case CONSTRUCTOR: case LAMBDA_EXPR: - tpvis = type_visibility (TREE_TYPE (*tp)); + tpvis = type_visibility (TREE_TYPE (t)); break; + case TEMPLATE_DECL: + if (DECL_ALIAS_TEMPLATE_P (t)) + /* FIXME: We don't maintain TREE_PUBLIC / DECL_VISIBILITY for + alias templates so we can't trust it here (PR107906). */ + break; + t = DECL_TEMPLATE_RESULT (t); + /* Fall through. */ case VAR_DECL: case FUNCTION_DECL: - if (! TREE_PUBLIC (*tp)) + if (! TREE_PUBLIC (t)) tpvis = VISIBILITY_ANON; else - tpvis = DECL_VISIBILITY (*tp); + tpvis = DECL_VISIBILITY (t); + break; + + case FIELD_DECL: + tpvis = type_visibility (DECL_CONTEXT (t)); break; default: diff --git a/gcc/testsuite/g++.dg/template/linkage2.C b/gcc/testsuite/g++.dg/template/linkage2.C new file mode 100644 index 00000000000..08fb6930262 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/linkage2.C @@ -0,0 +1,13 @@ +// PR c++/70413 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler-not "(weak|glob)\[^\n\]*_Z" } } + +namespace { + template struct A; +} + +template class Q> void f() { } + +int main() { + f(); +} diff --git a/gcc/testsuite/g++.dg/template/linkage3.C b/gcc/testsuite/g++.dg/template/linkage3.C new file mode 100644 index 00000000000..257aab33b38 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/linkage3.C @@ -0,0 +1,17 @@ +// PR c++/70413 +// { dg-final { scan-assembler-not "(weak|glob)\[^\n\]*_Z" } } + +namespace { + struct A { + void f(); + int m; + }; +} + +template void g() { } +template void h() { } + +int main() { + g<&A::f>(); + h<&A::m>(); +} diff --git a/gcc/testsuite/g++.dg/template/linkage4.C b/gcc/testsuite/g++.dg/template/linkage4.C new file mode 100644 index 00000000000..03630eebd3d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/linkage4.C @@ -0,0 +1,16 @@ +// PR c++/107906 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler-not "(weak|glob)\[^\n\]*_Z" { xfail *-*-* } } } + +namespace { + template using X = int; + struct A { + template using X = int; + }; +} +template class Q> void f() { } + +int main() { + f(); + f(); +} diff --git a/gcc/testsuite/g++.dg/template/linkage4a.C b/gcc/testsuite/g++.dg/template/linkage4a.C new file mode 100644 index 00000000000..f1934fd6557 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/linkage4a.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler "(weak|glob)\[^\n\]*_Z1fI1XEvv" } } +// { dg-final { scan-assembler "(weak|glob)\[^\n\]*_Z1fIN1A1XEEvv" } } + +template using X = int; +struct A { + template using X = int; +}; +template class Q> void f() { } + +int main() { + f(); + f(); +} -- 2.11.4.GIT