Patchwork [C++] PR 30066

login
register
mail settings
Submitter Roberto Agostino Vitillo
Date Oct. 21, 2011, 8 a.m.
Message ID <1F1A5107-8C1D-411E-9048-EECA2EE3764E@lbl.gov>
Download mbox | patch
Permalink /patch/120955/
State New
Headers show

Comments

Roberto Agostino Vitillo - Oct. 21, 2011, 8 a.m.
With this patch fvisibility-inlines-hidden affects also inline functions, e.g.:


inline void foo() {}

int main(){
  foo();
  return 0;
} 

when compiled with -fvisibility-inlines-hidden, foo has hidden visibility:
...
   10: 0000000000000000     6 FUNC    WEAK   HIDDEN     6 _Z3foov
...


Tested on x86_64-linux. I should have a signed copyright assignment in a few weeks but I think this patch is small enough that it doesn't need it.
r

2011-10-21  Roberto Agostino Vitillo  <ravitillo@lbl.gov>

	PR c++/30066
	* gcc/doc/invoke.texi: Documentation change for fvisibility-inlines-hidden.
	
	* gcc/c-family/c.opt: Description change for fvisibility-inlines-hidden.
	
	* gcc/cp/decl2.c (determine_hidden_inline): New function.
	  (determine_visibility): fvisibility-inlines-hidden affects inline functions.
	
	* gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C: New test.
Roberto Agostino Vitillo - Oct. 21, 2011, 9:52 a.m.
I am resubmitting the changelog since it was not respecting the conventions.

gcc/Changelog:
2011-10-21  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
	PR c++/30066
	* doc/invoke.texi (fvisibility-inlines-hidden): Documentation change.

gcc/c-family/Changelog:
2011-10-21  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
	PR c++/30066	
	* c.opt (fvisibility-inlines-hidden): Description change.
	
gcc/cp/Changelog:
2011-10-21  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
	PR c++/30066
	* decl2.c (determine_hidden_inline): New function.
	  (determine_visibility): fvisibility-inlines-hidden affects inline functions.

gcc/testsuite/Changelog:
2011-10-21  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
	PR c++/30066
	* g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C: New test.

r
Jason Merrill - Oct. 21, 2011, 2:16 p.m.
Need to make sure that this comment is still accurate:

>           /* Local statics and classes get the visibility of their
>              containing function by default, except that
>              -fvisibility-inlines-hidden doesn't affect them.  */

i.e. given

inline int * f() { static int i; return &i; }

int main()
{
   f();
}

f()::i should not be hidden, nor should a local class.

Jason

Patch

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 180234)
+++ gcc/doc/invoke.texi	(working copy)
@@ -2120,7 +2120,7 @@ 
 @item -fvisibility-inlines-hidden
 @opindex fvisibility-inlines-hidden
 This switch declares that the user does not attempt to compare
-pointers to inline methods where the addresses of the two functions
+pointers to inline functions or methods where the addresses of the two functions
 were taken in different shared objects.
 
 The effect of this is that GCC may, effectively, mark inline methods with
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 180234)
+++ gcc/c-family/c.opt	(working copy)
@@ -1043,7 +1043,7 @@ 
 
 fvisibility-inlines-hidden
 C++ ObjC++
-Marks all inlined methods as having hidden visibility
+Marks all inlined functions and methods as having hidden visibility
 
 fvisibility-ms-compat
 C++ ObjC++ Var(flag_visibility_ms_compat)
Index: gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C
===================================================================
--- gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C	(revision 0)
@@ -0,0 +1,18 @@ 
+/* PR c++/30066: Test that -fvisibility-inlines-hidden affects functions. */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-fvisibility-inlines-hidden" } */
+/* { dg-final { scan-hidden "_Z3barv" } } */
+/* { dg-final { scan-hidden "_Z3fooIvEvv" } } */
+
+inline void bar() { }
+
+template <class T>
+inline void foo() { }
+
+int main(void)
+{
+  bar();
+  foo<void>();
+  return 0;
+}
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 180234)
+++ gcc/cp/decl2.c	(working copy)
@@ -86,6 +86,7 @@ 
 static void import_export_class (tree);
 static tree get_guard_bits (tree);
 static void determine_visibility_from_class (tree, tree);
+static bool determine_hidden_inline (tree);
 static bool decl_defined_p (tree);
 
 /* A list of static class variables.  This is needed, because a
@@ -2131,13 +2132,16 @@ 
 	}
       else if (use_template)
 	/* Template instantiations and specializations get visibility based
-	   on their template unless they override it with an attribute.  */;
+ 	   on their template unless they override it with an attribute.  */;
       else if (! DECL_VISIBILITY_SPECIFIED (decl))
 	{
-	  /* Set default visibility to whatever the user supplied with
-	     #pragma GCC visibility or a namespace visibility attribute.  */
-	  DECL_VISIBILITY (decl) = default_visibility;
-	  DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
+          if (!determine_hidden_inline (decl))
+            {
+	      /* Set default visibility to whatever the user supplied with
+	         #pragma GCC visibility or a namespace visibility attribute.  */
+	      DECL_VISIBILITY (decl) = default_visibility;
+	      DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
+            }
 	}
     }
 
@@ -2155,7 +2159,9 @@ 
 	  int depth = TMPL_ARGS_DEPTH (args);
 	  tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
 
-	  if (!DECL_VISIBILITY_SPECIFIED (decl))
+	  if (!DECL_VISIBILITY_SPECIFIED (decl)
+	      && (DECL_VISIBILITY_SPECIFIED (pattern) 
+	          || !determine_hidden_inline (decl)))
 	    {
 	      DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
 	      DECL_VISIBILITY_SPECIFIED (decl)
@@ -2214,17 +2220,7 @@ 
   if (DECL_VISIBILITY_SPECIFIED (decl))
     return;
 
-  if (visibility_options.inlines_hidden
-      /* Don't do this for inline templates; specializations might not be
-	 inline, and we don't want them to inherit the hidden
-	 visibility.  We'll set it here for all inline instantiations.  */
-      && !processing_template_decl
-      && TREE_CODE (decl) == FUNCTION_DECL
-      && DECL_DECLARED_INLINE_P (decl)
-      && (! DECL_LANG_SPECIFIC (decl)
-	  || ! DECL_EXPLICIT_INSTANTIATION (decl)))
-    DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
-  else
+  if (!determine_hidden_inline (decl))
     {
       /* Default to the class visibility.  */
       DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
@@ -2247,6 +2243,26 @@ 
     targetm.cxx.determine_class_data_visibility (decl);
 }
 
+static bool
+determine_hidden_inline (tree decl)
+{
+  if (visibility_options.inlines_hidden
+      /* Don't do this for inline templates; specializations might not be
+       * inline, and we don't want them to inherit the hidden
+       * visibility.  We'll set it here for all inline instantiations.  */
+      && !processing_template_decl
+      && TREE_CODE (decl) == FUNCTION_DECL
+      && DECL_DECLARED_INLINE_P (decl)
+      && (! DECL_LANG_SPECIFIC (decl)
+          || ! DECL_EXPLICIT_INSTANTIATION (decl)))
+    {
+      DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+      return true;
+    }
+
+  return false;
+}
+
 /* Constrain the visibility of a class TYPE based on the visibility of its
    field types.  Warn if any fields require lesser visibility.  */