Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?
-- >8 -- When constraining the visibility of an instantiation, we weren't properly considering the visibility of PTRMEM_CST and TEMPLATE_DECL template arguments. PR c++/70413 gcc/cp/ChangeLog: * decl2.cc (min_vis_expr_r): Handle PTRMEM_CST and TEMPLATE_DECL. gcc/testsuite/ChangeLog: * g++.dg/abi/no-linkage-expr2.C: New test. * g++.dg/abi/no-linkage-expr3.C: New test. --- gcc/cp/decl2.cc | 18 ++++++++++++++---- gcc/testsuite/g++.dg/abi/no-linkage-expr2.C | 15 +++++++++++++++ gcc/testsuite/g++.dg/abi/no-linkage-expr3.C | 17 +++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/no-linkage-expr2.C create mode 100644 gcc/testsuite/g++.dg/abi/no-linkage-expr3.C diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index b402befba6d..5006372a646 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2582,7 +2582,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: @@ -2593,15 +2596,22 @@ 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: + 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/abi/no-linkage-expr2.C b/gcc/testsuite/g++.dg/abi/no-linkage-expr2.C new file mode 100644 index 00000000000..db23570bb08 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/no-linkage-expr2.C @@ -0,0 +1,15 @@ +// PR c++/70413 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler-not "weak.*_Z" } } + +namespace { + template<class> struct A; + template<class> using B = int; +} + +template<template<class> class Q> void f() { } + +int main() { + f<A>(); + f<B>(); +} diff --git a/gcc/testsuite/g++.dg/abi/no-linkage-expr3.C b/gcc/testsuite/g++.dg/abi/no-linkage-expr3.C new file mode 100644 index 00000000000..a2db1a45c74 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/no-linkage-expr3.C @@ -0,0 +1,17 @@ +// PR c++/70413 +// { dg-final { scan-assembler-not "weak.*_Z" } } + +namespace { + struct A { + void f(); + int m; + }; +} + +template<void(A::*)()> void g() { } +template<int A::*> void h() { } + +int main() { + g<&A::f>(); + h<&A::m>(); +} -- 2.42.0.158.g94e83dcf5b