This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: another visibility tweak


On further consideration, I think that propagating visibility from types to decls will be more surprising than useful, so I've disabled that. This patch also restricts the warning about a field with lower visibility to cases where the field has class type; no need to worry about pointer fields.

Tested x86_64-pc-linux-gnu, applied to trunk.
2006-07-21  Jason Merrill  <jason@redhat.com>

	* decl2.c (determine_visibility): Don't propagate visibility from
	type to decl.
	(constrain_class_visibility): Don't warn in system headers.
	Don't warn about pointer fields.

Index: doc/invoke.texi
===================================================================
*** doc/invoke.texi	(revision 115647)
--- doc/invoke.texi	(working copy)
*************** the function is defined in only one shar
*** 1625,1631 ****
  You may mark a method as having a visibility explicitly to negate the
  effect of the switch for that method.  For example, if you do want to
  compare pointers to a particular inline method, you might mark it as
! having default visibility.
  
  @item -fno-weak
  @opindex fno-weak
--- 1625,1632 ----
  You may mark a method as having a visibility explicitly to negate the
  effect of the switch for that method.  For example, if you do want to
  compare pointers to a particular inline method, you might mark it as
! having default visibility.  Marking the enclosing class with explicit
! visibility will have no effect.
  
  @item -fno-weak
  @opindex fno-weak
Index: testsuite/g++.dg/ext/visibility/warn1.C
===================================================================
*** testsuite/g++.dg/ext/visibility/warn1.C	(revision 115647)
--- testsuite/g++.dg/ext/visibility/warn1.C	(working copy)
***************
*** 1,13 ****
- // Warn when a declaration is specified with greater visibility than that
- // of its type.
- 
- // { dg-do compile }
- // { dg-require-visibility "" }
- // { dg-final { scan-hidden "_Z1fv" } }
- 
- namespace N __attribute ((__visibility__ ("hidden")))
- {
-   struct A { };
- }
- 
- N::A f() { } // { dg-warning "visibility" "" }
--- 0 ----
Index: testsuite/g++.dg/ext/visibility/warn2.C
===================================================================
*** testsuite/g++.dg/ext/visibility/warn2.C	(revision 115647)
--- testsuite/g++.dg/ext/visibility/warn2.C	(working copy)
***************
*** 1,6 ****
  // Complain when a class is specified with greater visibility than one of
! // its members' types or bases, and when a declaration has greater
! // visibility than its type.
  
  // { dg-require-visibility "" }
  
--- 1,5 ----
  // Complain when a class is specified with greater visibility than one of
! // its members' types or bases.
  
  // { dg-require-visibility "" }
  
*************** struct B
*** 14,19 ****
    N::A a;
  };
  
- N::A f () { }			// { dg-warning "visibility" }
- 
  struct C: public N::A { };	// { dg-warning "visibility" }
--- 13,16 ----
Index: testsuite/g++.dg/ext/visibility/warn3.C
===================================================================
*** testsuite/g++.dg/ext/visibility/warn3.C	(revision 115647)
--- testsuite/g++.dg/ext/visibility/warn3.C	(working copy)
*************** struct __attribute ((visibility ("hidden
*** 12,25 ****
  
  void A::f() { }
  
! // This gets a warning; it should have explicit visibility of some sort.
! A* afactory1() { return new A; }	// { dg-warning "visibility" }
! 
! // This is OK.
! __attribute ((visibility ("default"))) A*
! afactory2 () { return new A; }
! 
! // This gets a warning.
  struct B
  {				// { dg-warning "visibility" }
    A a;
--- 12,19 ----
  
  void A::f() { }
  
! // This gets a warning because B objects might rely
! // on hidden symbols from A.
  struct B
  {				// { dg-warning "visibility" }
    A a;
Index: cp/decl2.c
===================================================================
*** cp/decl2.c	(revision 115647)
--- cp/decl2.c	(working copy)
*************** determine_visibility (tree decl)
*** 1775,1791 ****
    if (class_type)
      determine_visibility_from_class (decl, class_type);
  
-   /* Don't let it have more visibility than its type.  */
-   if (TREE_CODE (decl) != TYPE_DECL)
-     if (constrain_visibility (decl, type_visibility (TREE_TYPE (decl))))
-       warning (OPT_Wattributes, "\
- lowering visibility of %q+D to match its type",
- 	       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);
  }
  
  /* By default, static data members and function members receive
--- 1775,1791 ----
    if (class_type)
      determine_visibility_from_class (decl, class_type);
  
    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);
+   else if (TREE_CODE (decl) != TYPE_DECL)
+     {
+       /* Propagate anonymity from type to decl.  */
+       int tvis = type_visibility (TREE_TYPE (decl));
+       if (tvis == VISIBILITY_ANON)
+ 	constrain_visibility (decl, tvis);
+     }
  }
  
  /* By default, static data members and function members receive
*************** constrain_class_visibility (tree type)
*** 1839,1845 ****
  
    int vis = type_visibility (type);
  
!   if (vis == VISIBILITY_ANON)
      return;
  
    /* Don't warn about visibility if the class has explicit visibility.  */
--- 1839,1846 ----
  
    int vis = type_visibility (type);
  
!   if (vis == VISIBILITY_ANON
!       || DECL_IN_SYSTEM_HEADER (TYPE_MAIN_DECL (type)))
      return;
  
    /* Don't warn about visibility if the class has explicit visibility.  */
*************** constrain_class_visibility (tree type)
*** 1849,1861 ****
    for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
      if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node)
        {
! 	int subvis = type_visibility (TREE_TYPE (t));
  
  	if (subvis == VISIBILITY_ANON)
  	  warning (0, "\
  %qT has a field %qD whose type uses the anonymous namespace",
  		   type, t);
! 	else if (vis < VISIBILITY_HIDDEN
  		 && subvis >= VISIBILITY_HIDDEN)
  	  warning (OPT_Wattributes, "\
  %qT declared with greater visibility than the type of its field %qD",
--- 1850,1864 ----
    for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
      if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node)
        {
! 	tree ftype = strip_array_types (TREE_TYPE (t));
! 	int subvis = type_visibility (ftype);
  
  	if (subvis == VISIBILITY_ANON)
  	  warning (0, "\
  %qT has a field %qD whose type uses the anonymous namespace",
  		   type, t);
! 	else if (IS_AGGR_TYPE (ftype)
! 		 && vis < VISIBILITY_HIDDEN
  		 && subvis >= VISIBILITY_HIDDEN)
  	  warning (OPT_Wattributes, "\
  %qT declared with greater visibility than the type of its field %qD",

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]