From: jason Date: Mon, 7 Nov 2011 04:40:14 +0000 (+0000) Subject: PR c++/35688 X-Git-Tag: upstream/4.9.2~16392 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b4f861b4e0d2475dd125ee4d055e8c33a45fbcba;p=platform%2Fupstream%2Flinaro-gcc.git PR c++/35688 gcc/c-common/ * c-common.c (decl_has_visibility_attr): Split out from... (c_determine_visibility): ...here. * c-common.h: Declare it. gcc/cp/ * decl2.c (constrain_visibility): Check decl_has_visibility_attr rather than DECL_VISIBILITY_SPECIFIED. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181069 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3829411..7b30b3b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2011-11-06 Jason Merrill + + PR c++/35688 + * c-common.c (decl_has_visibility_attr): Split out from... + (c_determine_visibility): ...here. + * c-common.h: Declare it. + 2011-11-06 Joseph Myers * c-common.c (c_common_reswords): Add _Alignas and _Alignof. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 0329bc7..92fb363 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7073,6 +7073,22 @@ 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. @@ -7088,15 +7104,8 @@ 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. 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))))) + the processing of the attribute. */ + if (decl_has_visibility_attr (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 bff6956..f914d49 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -775,6 +775,7 @@ 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 f374af6..201c2c1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2011-11-06 Jason Merrill + + PR c++/35688 + * decl2.c (constrain_visibility): Check decl_has_visibility_attr + rather than DECL_VISIBILITY_SPECIFIED. + 2011-11-06 Paolo Carlini PR c++/47695 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index f4499b5..80fb0c3 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1974,8 +1974,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_VISIBILITY_SPECIFIED (decl)) + && !decl_has_visibility_attr (decl)) { DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility; return true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fc0938c..1f9aa81 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-06 Jason Merrill + + PR c++/35688 + * g++.dg/ext/visibility/template7.C: New. + 2011-11-07 Terry Guo * gcc.target/arm/wmul-1.c: Adjust optimization level. diff --git a/gcc/testsuite/g++.dg/ext/visibility/template7.C b/gcc/testsuite/g++.dg/ext/visibility/template7.C new file mode 100644 index 0000000..5197fb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template7.C @@ -0,0 +1,29 @@ +// PR c++/35688 +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } + +// { dg-final { scan-hidden "_ZN1s6vectorI1AEC1Ev" } } +// { dg-final { scan-hidden "_ZN1s3fooI1AEEvT_" } } + +namespace s __attribute__((visibility("default"))) { + template + class vector { + public: + vector() { } + }; + template + void foo(T t) { + } +} + +class A { +public: + A() { } +}; + +s::vector v; + +int main() { + A a; + s::foo(a); +}