From bd65538abb6a48c97f9fd02d037b41e5a6397a70 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 7 Jan 2020 10:05:25 -0500 Subject: [PATCH] PR c++/47877 - -fvisibility-inlines-hidden and member templates. DECL_VISIBILITY_SPECIFIED is also true if an enclosing scope has explicit visibility, and we don't want that to override -fvisibility-inlines-hidden. So check for the attribute specifically on the function, like we already do for template argument visibility restriction. * decl2.c (determine_visibility): -fvisibility-inlines-hidden beats explicit class visibility for a template. From-SVN: r279960 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/decl2.c | 5 +++-- .../ext/visibility/fvisibility-inlines-hidden-5.C | 13 +++++++++++++ gcc/tree.h | 4 ++-- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a82b6cf2f21..a7234b89467 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-01-07 Jason Merrill + + PR c++/47877 - -fvisibility-inlines-hidden and member templates. + * decl2.c (determine_visibility): -fvisibility-inlines-hidden beats + explicit class visibility for a template. + 2020-01-07 Richard Sandiford * mangle.c (mangle_type_attribute_p): New function, split out from... diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 9fb1d81a881..a641667991f 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2629,6 +2629,7 @@ determine_visibility (tree decl) tree attribs = (TREE_CODE (decl) == TYPE_DECL ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : DECL_ATTRIBUTES (decl)); + tree attr = lookup_attribute ("visibility", attribs); if (args != error_mark_node) { @@ -2636,7 +2637,7 @@ determine_visibility (tree decl) if (!DECL_VISIBILITY_SPECIFIED (decl)) { - if (!DECL_VISIBILITY_SPECIFIED (pattern) + if (!attr && determine_hidden_inline (decl)) DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; else @@ -2650,7 +2651,7 @@ determine_visibility (tree decl) if (args /* Template argument visibility outweighs #pragma or namespace visibility, but not an explicit attribute. */ - && !lookup_attribute ("visibility", attribs)) + && !attr) { int depth = TMPL_ARGS_DEPTH (args); if (DECL_VISIBILITY_SPECIFIED (decl)) diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-5.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-5.C new file mode 100644 index 00000000000..2937f35d9a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-5.C @@ -0,0 +1,13 @@ +// PR c++/47877 +// { dg-options "-fvisibility-inlines-hidden" } +// { dg-require-visibility "" } +// { dg-final { scan-hidden "_ZN3Foo3barIS_EEvv" } } + +struct __attribute__((visibility("default"))) Foo { + template inline void bar() {}; +}; + +int main() +{ + Foo().bar(); +} diff --git a/gcc/tree.h b/gcc/tree.h index a6e4e9e6b8c..9ca9ab58ec0 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2903,8 +2903,8 @@ extern void decl_value_expr_insert (tree, tree); #define DECL_VISIBILITY(NODE) \ (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility) -/* Nonzero means that the decl had its visibility specified rather than - being inferred. */ +/* Nonzero means that the decl (or an enclosing scope) had its + visibility specified rather than being inferred. */ #define DECL_VISIBILITY_SPECIFIED(NODE) \ (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility_specified) -- 2.30.2