diff options
-rw-r--r-- | gcc/c-family/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 27 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 1 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 27 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/visibility/template8.C | 26 |
8 files changed, 65 insertions, 34 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7b30b3b..04134ec 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2011-11-07 Jason Merrill <jason@redhat.com> + + PR c++/35688 + * c-common.c, c-common.h: Revert yesterday's changes. + 2011-11-06 Jason Merrill <jason@redhat.com> PR c++/35688 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 92fb363..0329bc7 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7073,22 +7073,6 @@ handle_visibility_attribute (tree *node, tree name, tree args, return NULL_TREE; } -/* Returns true iff DECL actually has visibility specified by an attribute. - We check for an explicit attribute, rather than just checking - DECL_VISIBILITY_SPECIFIED, to distinguish the use of an attribute from - the use of a "#pragma GCC visibility push(...)"; in the latter case we - still want other considerations to be able to overrule the #pragma. */ - -bool -decl_has_visibility_attr (tree decl) -{ - tree attrs = DECL_ATTRIBUTES (decl); - return (lookup_attribute ("visibility", attrs) - || (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && (lookup_attribute ("dllimport", attrs) - || lookup_attribute ("dllexport", attrs)))); -} - /* Determine the ELF symbol visibility for DECL, which is either a variable or a function. It is an error to use this function if a definition of DECL is not available in this translation unit. @@ -7104,8 +7088,15 @@ c_determine_visibility (tree decl) /* If the user explicitly specified the visibility with an attribute, honor that. DECL_VISIBILITY will have been set during - the processing of the attribute. */ - if (decl_has_visibility_attr (decl)) + the processing of the attribute. We check for an explicit + attribute, rather than just checking DECL_VISIBILITY_SPECIFIED, + to distinguish the use of an attribute from the use of a "#pragma + GCC visibility push(...)"; in the latter case we still want other + considerations to be able to overrule the #pragma. */ + if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)) + || (TARGET_DLLIMPORT_DECL_ATTRIBUTES + && (lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)) + || lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))))) return true; /* Set default visibility to whatever the user supplied with diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index f914d49..bff6956 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -775,7 +775,6 @@ extern void overflow_warning (location_t, tree); extern void warn_logical_operator (location_t, enum tree_code, tree, enum tree_code, tree, enum tree_code, tree); extern void check_main_parameter_types (tree decl); -extern bool decl_has_visibility_attr (tree); extern bool c_determine_visibility (tree); extern bool same_scalar_type_ignoring_signedness (tree, tree); extern void mark_valid_location_for_stdc_pragma (bool); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 41922ae..c66c9dc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2011-11-07 Jason Merrill <jason@redhat.com> + PR c++/35688 + * decl2.c (constrain_visibility): Return void. Add tmpl parm + which gives the constraint priority over an attribute. + (constrain_visibility_for_template, determine_visibility): Adjust. + * pt.c (instantiate_class_template_1): Call determine_visibility. + PR c++/33255 * decl.c (save_function_data): Clear local_typedefs. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 80fb0c3..17be3ad 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1954,10 +1954,12 @@ type_visibility (tree type) } /* Limit the visibility of DECL to VISIBILITY, if not explicitly - specified (or if VISIBILITY is static). */ + specified (or if VISIBILITY is static). If TMPL is true, this + constraint is for a template argument, and takes precedence + over explicitly-specified visibility on the template. */ -static bool -constrain_visibility (tree decl, int visibility) +static void +constrain_visibility (tree decl, int visibility, bool tmpl) { if (visibility == VISIBILITY_ANON) { @@ -1974,16 +1976,11 @@ constrain_visibility (tree decl, int visibility) DECL_NOT_REALLY_EXTERN (decl) = 1; } } - /* We check decl_has_visibility_attr rather than - DECL_VISIBILITY_SPECIFIED here because we want other considerations - to override visibility from a namespace or #pragma. */ else if (visibility > DECL_VISIBILITY (decl) - && !decl_has_visibility_attr (decl)) + && (tmpl || !DECL_VISIBILITY_SPECIFIED (decl))) { DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility; - return true; } - return false; } /* Constrain the visibility of DECL based on the visibility of its template @@ -2019,7 +2016,7 @@ constrain_visibility_for_template (tree decl, tree targs) } } if (vis) - constrain_visibility (decl, vis); + constrain_visibility (decl, vis, true); } } @@ -2132,7 +2129,7 @@ determine_visibility (tree decl) if (underlying_vis == VISIBILITY_ANON || (CLASS_TYPE_P (underlying_type) && CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type))) - constrain_visibility (decl, underlying_vis); + constrain_visibility (decl, underlying_vis, false); else DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; } @@ -2140,7 +2137,7 @@ determine_visibility (tree decl) { /* tinfo visibility is based on the type it's for. */ constrain_visibility - (decl, type_visibility (TREE_TYPE (DECL_NAME (decl)))); + (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))), false); /* Give the target a chance to override the visibility associated with DECL. */ @@ -2207,14 +2204,14 @@ determine_visibility (tree decl) if (decl_anon_ns_mem_p (decl)) /* Names in an anonymous namespace get internal linkage. This might change once we implement export. */ - constrain_visibility (decl, VISIBILITY_ANON); + constrain_visibility (decl, VISIBILITY_ANON, false); else if (TREE_CODE (decl) != TYPE_DECL) { /* Propagate anonymity from type to decl. */ int tvis = type_visibility (TREE_TYPE (decl)); if (tvis == VISIBILITY_ANON || ! DECL_VISIBILITY_SPECIFIED (decl)) - constrain_visibility (decl, tvis); + constrain_visibility (decl, tvis, false); } else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true)) /* DR 757: A type without linkage shall not be used as the type of a @@ -2225,7 +2222,7 @@ determine_visibility (tree decl) Since non-extern "C" decls need to be defined in the same translation unit, we can make the type internal. */ - constrain_visibility (decl, VISIBILITY_ANON); + constrain_visibility (decl, VISIBILITY_ANON, false); /* If visibility changed and DECL already has DECL_RTL, ensure symbol flags are updated. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 493e3e6..52f4d47 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8600,6 +8600,8 @@ instantiate_class_template_1 (tree type) { CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1; CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern); + /* Adjust visibility for template arguments. */ + determine_visibility (TYPE_MAIN_DECL (type)); } CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 46f702a..b9c39d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-07 Jason Merrill <jason@redhat.com> + + PR c++/35688 + * g++.dg/ext/visibility/template8.C: New. + 2011-11-07 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/50789 diff --git a/gcc/testsuite/g++.dg/ext/visibility/template8.C b/gcc/testsuite/g++.dg/ext/visibility/template8.C new file mode 100644 index 0000000..e491882 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template8.C @@ -0,0 +1,26 @@ +// PR c++/35688 +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } + +// { dg-final { scan-hidden "_Z1gI1BEvT_" } } +// { dg-final { scan-hidden "_Z1gI1AI1BEEvT_" } } + +// Test that template argument visibility takes priority even over an +// explicit visibility attribute on a template. + +template <class T> +struct __attribute ((visibility ("default"))) A { }; +template <class T> +void g(T) __attribute ((visibility ("default"))); + +struct B { }; + +template <class T> +void g(T) +{ } + +int main() +{ + g(B()); + g(A<B>()); +} |