Commit fb9120e3 by Roberto Agostino Vitillo Committed by Jason Merrill

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
parent 2bea3d91
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> 2011-10-26 Ed Smith-Rowland <3dw4rd@verizon.net>
Implement C++11 user-defined literals. Implement C++11 user-defined literals.
......
...@@ -1043,7 +1043,7 @@ Use __cxa_get_exception_ptr in exception handling ...@@ -1043,7 +1043,7 @@ Use __cxa_get_exception_ptr in exception handling
fvisibility-inlines-hidden fvisibility-inlines-hidden
C++ ObjC++ C++ ObjC++
Marks all inlined methods as having hidden visibility Marks all inlined functions and methods as having hidden visibility
fvisibility-ms-compat fvisibility-ms-compat
C++ ObjC++ Var(flag_visibility_ms_compat) C++ ObjC++ Var(flag_visibility_ms_compat)
......
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> 2011-10-27 Dodji Seketeli <dodji@redhat.com>
* cp-tree.h (DECL_DECLARES_TYPE_P): Fix comment. * cp-tree.h (DECL_DECLARES_TYPE_P): Fix comment.
......
...@@ -86,6 +86,7 @@ static void write_out_vars (tree); ...@@ -86,6 +86,7 @@ static void write_out_vars (tree);
static void import_export_class (tree); static void import_export_class (tree);
static tree get_guard_bits (tree); static tree get_guard_bits (tree);
static void determine_visibility_from_class (tree, tree); static void determine_visibility_from_class (tree, tree);
static bool determine_hidden_inline (tree);
static bool decl_defined_p (tree); static bool decl_defined_p (tree);
/* A list of static class variables. This is needed, because a /* A list of static class variables. This is needed, because a
...@@ -2088,14 +2089,29 @@ determine_visibility (tree decl) ...@@ -2088,14 +2089,29 @@ determine_visibility (tree decl)
containing function by default, except that containing function by default, except that
-fvisibility-inlines-hidden doesn't affect them. */ -fvisibility-inlines-hidden doesn't affect them. */
tree fn = DECL_CONTEXT (decl); 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 (decl) = DECL_VISIBILITY (fn);
DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (decl) =
DECL_VISIBILITY_SPECIFIED (fn); DECL_VISIBILITY_SPECIFIED (fn);
} }
else 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, /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
but have no TEMPLATE_INFO, so don't try to check it. */ but have no TEMPLATE_INFO, so don't try to check it. */
...@@ -2134,10 +2150,15 @@ determine_visibility (tree decl) ...@@ -2134,10 +2150,15 @@ determine_visibility (tree decl)
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)) else if (! DECL_VISIBILITY_SPECIFIED (decl))
{ {
/* Set default visibility to whatever the user supplied with if (determine_hidden_inline (decl))
#pragma GCC visibility or a namespace visibility attribute. */ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY (decl) = default_visibility; else
DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma; {
/* 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) ...@@ -2157,9 +2178,15 @@ determine_visibility (tree decl)
if (!DECL_VISIBILITY_SPECIFIED (decl)) if (!DECL_VISIBILITY_SPECIFIED (decl))
{ {
DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern); if (!DECL_VISIBILITY_SPECIFIED (pattern)
DECL_VISIBILITY_SPECIFIED (decl) && determine_hidden_inline (decl))
= DECL_VISIBILITY_SPECIFIED (pattern); 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? */ /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
...@@ -2214,15 +2241,7 @@ determine_visibility_from_class (tree decl, tree class_type) ...@@ -2214,15 +2241,7 @@ determine_visibility_from_class (tree decl, tree class_type)
if (DECL_VISIBILITY_SPECIFIED (decl)) if (DECL_VISIBILITY_SPECIFIED (decl))
return; return;
if (visibility_options.inlines_hidden if (determine_hidden_inline (decl))
/* 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; DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
else else
{ {
...@@ -2247,6 +2266,23 @@ determine_visibility_from_class (tree decl, tree class_type) ...@@ -2247,6 +2266,23 @@ determine_visibility_from_class (tree decl, tree class_type)
targetm.cxx.determine_class_data_visibility (decl); 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 /* Constrain the visibility of a class TYPE based on the visibility of its
field types. Warn if any fields require lesser visibility. */ field types. Warn if any fields require lesser visibility. */
......
...@@ -2120,7 +2120,7 @@ if the runtime routine is not available. ...@@ -2120,7 +2120,7 @@ if the runtime routine is not available.
@item -fvisibility-inlines-hidden @item -fvisibility-inlines-hidden
@opindex fvisibility-inlines-hidden @opindex fvisibility-inlines-hidden
This switch declares that the user does not attempt to compare 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. were taken in different shared objects.
The effect of this is that GCC may, effectively, mark inline methods with The effect of this is that GCC may, effectively, mark inline methods with
......
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> 2011-10-27 Jakub Jelinek <jakub@redhat.com>
* gcc.target/i386/sse2-cvt-1.c: New test. * gcc.target/i386/sse2-cvt-1.c: New test.
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment