OSDN Git Service

PR c++/30066
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Oct 2011 02:18:00 +0000 (02:18 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Oct 2011 02:18:00 +0000 (02:18 +0000)
gcc/c-family:
* c.opt (fvisibility-inlines-hidden): Description change.
gcc/cp:
* decl2.c (determine_hidden_inline): New function.
(determine_visibility): fvisibility-inlines-hidden affects inline
functions.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180589 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C [new file with mode: 0644]

index b49e827..02e823f 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-27  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
+
+       PR c++/30066
+       * c.opt (fvisibility-inlines-hidden): Description change.
+
 2011-10-26  Ed Smith-Rowland  <3dw4rd@verizon.net>
 
        Implement C++11 user-defined literals.
index bfc1a7c..693f191 100644 (file)
@@ -1043,7 +1043,7 @@ Use __cxa_get_exception_ptr in exception handling
 
 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 f7b6fbc..fe0665d 100644 (file)
@@ -1,3 +1,10 @@
+2011-10-27  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
+
+       PR c++/30066
+       * decl2.c (determine_hidden_inline): New function.
+       (determine_visibility): fvisibility-inlines-hidden affects inline
+       functions.
+
 2011-10-27  Dodji Seketeli  <dodji@redhat.com>
 
        * cp-tree.h (DECL_DECLARES_TYPE_P): Fix comment.
index 9851ece..be9044b 100644 (file)
@@ -86,6 +86,7 @@ static void write_out_vars (tree);
 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
@@ -2088,14 +2089,29 @@ determine_visibility (tree decl)
             containing function by default, except that
             -fvisibility-inlines-hidden doesn't affect them.  */
          tree fn = DECL_CONTEXT (decl);
-         if (DECL_VISIBILITY_SPECIFIED (fn) || ! DECL_CLASS_SCOPE_P (fn))
+         if (DECL_VISIBILITY_SPECIFIED (fn))
            {
              DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
              DECL_VISIBILITY_SPECIFIED (decl) = 
                DECL_VISIBILITY_SPECIFIED (fn);
            }
          else
-           determine_visibility_from_class (decl, DECL_CONTEXT (fn));
+           {
+             if (DECL_CLASS_SCOPE_P (fn))
+               determine_visibility_from_class (decl, DECL_CONTEXT (fn));
+             else if (determine_hidden_inline (fn))
+               {
+                 DECL_VISIBILITY (decl) = default_visibility;
+                 DECL_VISIBILITY_SPECIFIED (decl) =
+                   visibility_options.inpragma;
+               }
+             else
+               {
+                 DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+                 DECL_VISIBILITY_SPECIFIED (decl) =
+                   DECL_VISIBILITY_SPECIFIED (fn);
+               }
+           }
 
          /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
             but have no TEMPLATE_INFO, so don't try to check it.  */
@@ -2134,10 +2150,15 @@ determine_visibility (tree decl)
           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))
+           DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+         else
+            {
+             /* 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;
+            }
        }
     }
 
@@ -2157,9 +2178,15 @@ determine_visibility (tree decl)
 
          if (!DECL_VISIBILITY_SPECIFIED (decl))
            {
-             DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
-             DECL_VISIBILITY_SPECIFIED (decl)
-               = DECL_VISIBILITY_SPECIFIED (pattern);
+             if (!DECL_VISIBILITY_SPECIFIED (pattern)
+                 && determine_hidden_inline (decl))
+               DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+             else
+               {
+                 DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
+                 DECL_VISIBILITY_SPECIFIED (decl)
+                   = DECL_VISIBILITY_SPECIFIED (pattern);
+               }
            }
 
          /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
@@ -2214,15 +2241,7 @@ determine_visibility_from_class (tree decl, tree class_type)
   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)))
+  if (determine_hidden_inline (decl))
     DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
   else
     {
@@ -2247,6 +2266,23 @@ determine_visibility_from_class (tree decl, tree class_type)
     targetm.cxx.determine_class_data_visibility (decl);
 }
 
+/* Returns true iff DECL is an inline that should get hidden visibility
+   because of -fvisibility-inlines-hidden.  */
+
+static bool
+determine_hidden_inline (tree decl)
+{
+  return (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)));
+}
+
 /* Constrain the visibility of a class TYPE based on the visibility of its
    field types.  Warn if any fields require lesser visibility.  */
 
index 3f7a31f..1aa0541 100644 (file)
@@ -2120,7 +2120,7 @@ if the runtime routine is not available.
 @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 1f6f027..1f1b77f 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-27  Roberto Agostino Vitillo  <ravitillo@lbl.gov>
+
+       PR c++/30066
+       * g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C: New test.
+
 2011-10-27  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.target/i386/sse2-cvt-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C
new file mode 100644 (file)
index 0000000..ebce2ba
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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-not-hidden "_ZZ3barvE1n" } } */
+/* { dg-final { scan-not-hidden "_Z3fooIiEvv" } } */
+/* { dg-final { scan-hidden "_Z3fooIvEvv" } } */
+/* { dg-final { scan-hidden "_ZZN1A5innerEvE1n" } } */
+
+inline int * bar()
+{
+  static int n;
+  return &n;
+}
+
+template <class T>
+inline void foo() { }
+
+template void foo<int>();
+
+namespace A __attribute__ ((visibility ("hidden")))
+{
+  inline int * inner()
+  {
+    static int n;
+    return &n;
+  }
+}
+
+int main(void)
+{
+  bar();
+  foo<void>();
+  A::inner();
+  return 0;
+}