View | Details | Raw Unified | Return to bug 35688
Collapse All | Expand All

(-)a/gcc/cp/decl2.c (-12 / +12 lines)
Lines 1939-1948 type_visibility (tree type) Link Here
1939
}
1939
}
1940
1940
1941
/* Limit the visibility of DECL to VISIBILITY, if not explicitly
1941
/* Limit the visibility of DECL to VISIBILITY, if not explicitly
1942
   specified (or if VISIBILITY is static).  */
1942
   specified (or if VISIBILITY is static).  If TMPL is true, this
1943
   constraint is for a template argument, and takes precedence
1944
   over explicitly-specified visibility on the template.  */
1943
1945
1944
static bool
1946
static void
1945
constrain_visibility (tree decl, int visibility)
1947
constrain_visibility (tree decl, int visibility, bool tmpl)
1946
{
1948
{
1947
  if (visibility == VISIBILITY_ANON)
1949
  if (visibility == VISIBILITY_ANON)
1948
    {
1950
    {
Lines 1960-1971 constrain_visibility (tree decl, int visibility) Link Here
1960
	}
1962
	}
1961
    }
1963
    }
1962
  else if (visibility > DECL_VISIBILITY (decl)
1964
  else if (visibility > DECL_VISIBILITY (decl)
1963
	   && !DECL_VISIBILITY_SPECIFIED (decl))
1965
	   && (tmpl || !DECL_VISIBILITY_SPECIFIED (decl)))
1964
    {
1966
    {
1965
      DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility;
1967
      DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility;
1966
      return true;
1967
    }
1968
    }
1968
  return false;
1969
}
1969
}
1970
1970
1971
/* Constrain the visibility of DECL based on the visibility of its template
1971
/* Constrain the visibility of DECL based on the visibility of its template
Lines 2001-2007 constrain_visibility_for_template (tree decl, tree targs) Link Here
2001
	    }
2001
	    }
2002
	}
2002
	}
2003
      if (vis)
2003
      if (vis)
2004
	constrain_visibility (decl, vis);
2004
	constrain_visibility (decl, vis, true);
2005
    }
2005
    }
2006
}
2006
}
2007
2007
Lines 2099-2105 determine_visibility (tree decl) Link Here
2099
	  if (underlying_vis == VISIBILITY_ANON
2099
	  if (underlying_vis == VISIBILITY_ANON
2100
	      || (CLASS_TYPE_P (underlying_type)
2100
	      || (CLASS_TYPE_P (underlying_type)
2101
		  && CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)))
2101
		  && CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)))
2102
	    constrain_visibility (decl, underlying_vis);
2102
	    constrain_visibility (decl, underlying_vis, false);
2103
	  else
2103
	  else
2104
	    DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
2104
	    DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
2105
	}
2105
	}
Lines 2107-2113 determine_visibility (tree decl) Link Here
2107
	{
2107
	{
2108
	  /* tinfo visibility is based on the type it's for.  */
2108
	  /* tinfo visibility is based on the type it's for.  */
2109
	  constrain_visibility
2109
	  constrain_visibility
2110
	    (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))));
2110
	    (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))), false);
2111
2111
2112
	  /* Give the target a chance to override the visibility associated
2112
	  /* Give the target a chance to override the visibility associated
2113
	     with DECL.  */
2113
	     with DECL.  */
Lines 2163-2176 determine_visibility (tree decl) Link Here
2163
  if (decl_anon_ns_mem_p (decl))
2163
  if (decl_anon_ns_mem_p (decl))
2164
    /* Names in an anonymous namespace get internal linkage.
2164
    /* Names in an anonymous namespace get internal linkage.
2165
       This might change once we implement export.  */
2165
       This might change once we implement export.  */
2166
    constrain_visibility (decl, VISIBILITY_ANON);
2166
    constrain_visibility (decl, VISIBILITY_ANON, false);
2167
  else if (TREE_CODE (decl) != TYPE_DECL)
2167
  else if (TREE_CODE (decl) != TYPE_DECL)
2168
    {
2168
    {
2169
      /* Propagate anonymity from type to decl.  */
2169
      /* Propagate anonymity from type to decl.  */
2170
      int tvis = type_visibility (TREE_TYPE (decl));
2170
      int tvis = type_visibility (TREE_TYPE (decl));
2171
      if (tvis == VISIBILITY_ANON
2171
      if (tvis == VISIBILITY_ANON
2172
	  || ! DECL_VISIBILITY_SPECIFIED (decl))
2172
	  || ! DECL_VISIBILITY_SPECIFIED (decl))
2173
	constrain_visibility (decl, tvis);
2173
	constrain_visibility (decl, tvis, false);
2174
    }
2174
    }
2175
  else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
2175
  else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
2176
    /* DR 757: A type without linkage shall not be used as the type of a
2176
    /* DR 757: A type without linkage shall not be used as the type of a
Lines 2181-2187 determine_visibility (tree decl) Link Here
2181
2181
2182
       Since non-extern "C" decls need to be defined in the same
2182
       Since non-extern "C" decls need to be defined in the same
2183
       translation unit, we can make the type internal.  */
2183
       translation unit, we can make the type internal.  */
2184
    constrain_visibility (decl, VISIBILITY_ANON);
2184
    constrain_visibility (decl, VISIBILITY_ANON, false);
2185
2185
2186
  /* If visibility changed and DECL already has DECL_RTL, ensure
2186
  /* If visibility changed and DECL already has DECL_RTL, ensure
2187
     symbol flags are updated.  */
2187
     symbol flags are updated.  */
(-)a/gcc/cp/pt.c (+2 lines)
Lines 8267-8272 instantiate_class_template (tree type) Link Here
8267
    {
8267
    {
8268
      CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1;
8268
      CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1;
8269
      CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern);
8269
      CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern);
8270
      /* Adjust visibility for template arguments.  */
8271
      determine_visibility (TYPE_MAIN_DECL (type));
8270
    }
8272
    }
8271
8273
8272
  pbinfo = TYPE_BINFO (pattern);
8274
  pbinfo = TYPE_BINFO (pattern);
(-)a/gcc/testsuite/g++.dg/ext/visibility/template7.C (+29 lines)
Line 0 Link Here
1
// PR c++/35688
2
// { dg-require-visibility "" }
3
// { dg-options "-fvisibility=hidden" }
4
5
// { dg-final { scan-hidden "_ZN1s6vectorI1AEC1Ev" } }
6
// { dg-final { scan-hidden "_ZN1s3fooI1AEEvT_" } }
7
8
namespace s __attribute__((visibility("default"))) {
9
  template <class T>
10
    class vector {
11
  public:
12
    vector() { }
13
  };
14
  template <class T>
15
    void foo(T t) {
16
  }
17
}
18
19
class A {
20
public:
21
  A() { }
22
};
23
24
s::vector<A> v;
25
26
int main() {
27
  A a;
28
  s::foo(a);
29
}
(-)a/gcc/testsuite/g++.dg/ext/visibility/template8.C (+26 lines)
Line 0 Link Here
1
// PR c++/35688
2
// { dg-require-visibility "" }
3
// { dg-options "-fvisibility=hidden" }
4
5
// { dg-final { scan-hidden "_Z1gI1BEvT_" } }
6
// { dg-final { scan-hidden "_Z1gI1AI1BEEvT_" } }
7
8
// Test that template argument visibility takes priority even over an
9
// explicit visibility attribute on a template.
10
11
template <class T>
12
struct __attribute ((visibility ("default"))) A { };
13
template <class T>
14
void g(T) __attribute ((visibility ("default")));
15
16
struct B { };
17
18
template <class T>
19
void g(T)
20
{ }
21
22
int main()
23
{
24
  g(B());
25
  g(A<B>());
26
}

Return to bug 35688