re PR c++/30066 (option to make inline functions hidden)

PR c++/30066
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.

From-SVN: r180589
This commit is contained in:
Roberto Agostino Vitillo 2011-10-28 02:18:00 +00:00 committed by Jason Merrill
parent 2bea3d9195
commit fb9120e3b1
7 changed files with 110 additions and 20 deletions

View 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.

View 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)

View 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.

View 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. */

View 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

View 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.

View File

@ -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;
}