diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-05 18:08:56 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-05 18:08:56 +0000 |
commit | dc3784b95b5d8bab30e3a0dbbe11de5bf42f30fc (patch) | |
tree | 69970c187ae03c1584473d7cc7e15f9cbfcee1a3 /gcc/cp/decl2.c | |
parent | 8919e4f8bf954c6bcc7dba93d1b90011c6065feb (diff) | |
download | gcc-dc3784b95b5d8bab30e3a0dbbe11de5bf42f30fc.tar.gz |
PR c++/51930
* decl2.c (determine_visibility): Correct calculation of class
args depth.
* decl.c (check_tag_decl): Adjust warning.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184946 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index bdc962abcf9..7eccf672546 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2181,12 +2181,8 @@ determine_visibility (tree decl) ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : DECL_ATTRIBUTES (decl)); - if (args != error_mark_node - /* Template argument visibility outweighs #pragma or namespace - visibility, but not an explicit attribute. */ - && !lookup_attribute ("visibility", attribs)) + if (args != error_mark_node) { - int depth = TMPL_ARGS_DEPTH (args); tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)); if (!DECL_VISIBILITY_SPECIFIED (decl)) @@ -2202,10 +2198,31 @@ determine_visibility (tree decl) } } - /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */ - if (args && depth > template_class_depth (class_type)) - /* Limit visibility based on its template arguments. */ - constrain_visibility_for_template (decl, args); + if (args + /* Template argument visibility outweighs #pragma or namespace + visibility, but not an explicit attribute. */ + && !lookup_attribute ("visibility", attribs)) + { + int depth = TMPL_ARGS_DEPTH (args); + int class_depth = 0; + if (class_type && CLASSTYPE_TEMPLATE_INFO (class_type)) + class_depth = TMPL_ARGS_DEPTH (CLASSTYPE_TI_ARGS (class_type)); + if (DECL_VISIBILITY_SPECIFIED (decl)) + { + /* A class template member with explicit visibility + overrides the class visibility, so we need to apply + all the levels of template args directly. */ + int i; + for (i = 1; i <= depth; ++i) + { + tree lev = TMPL_ARGS_LEVEL (args, i); + constrain_visibility_for_template (decl, lev); + } + } + else if (depth > class_depth) + /* Limit visibility based on its template arguments. */ + constrain_visibility_for_template (decl, args); + } } } |