toplev.c (wrapup_global_declarations): Clarify variable handling.

* toplev.c (wrapup_global_declarations): Clarify variable handling.
        -fkeep-static-consts doesn't apply to comdats.

cp/
        * decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
        variables.
        * decl2.c (maybe_make_one_only): Also mark the decl as needed.

From-SVN: r50802
This commit is contained in:
Jason Merrill 2002-03-15 04:54:42 -05:00 committed by Jason Merrill
parent 0f9b56dcb2
commit 5cc90635da
6 changed files with 67 additions and 23 deletions

View file

@ -1,3 +1,8 @@
2002-03-15 Jason Merrill <jason@redhat.com>
* toplev.c (wrapup_global_declarations): Clarify variable handling.
-fkeep-static-consts doesn't apply to comdats.
2002-03-14 Richard Henderson <rth@redhat.com>
* c-decl.c: Include c-pragma.h.

View file

@ -1,3 +1,9 @@
2002-03-15 Jason Merrill <jason@redhat.com>
* decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
variables.
* decl2.c (maybe_make_one_only): Also mark the decl as needed.
2002-03-14 Richard Henderson <rth@redhat.com>
* decl.c: Include c-pragma.h.

View file

@ -7861,18 +7861,21 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
DECL_STMT is expanded. */
defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
/* We try to defer namespace-scope static constants so that they are
not emitted into the object file unnecessarily. */
if (!DECL_VIRTUAL_P (decl)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != NULL_TREE
&& DECL_INITIAL (decl) != error_mark_node
&& ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
&& toplev
&& !TREE_PUBLIC (decl))
/* We try to defer namespace-scope static constants and template
instantiations so that they are not emitted into the object file
unnecessarily. */
if ((!DECL_VIRTUAL_P (decl)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != NULL_TREE
&& DECL_INITIAL (decl) != error_mark_node
&& ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
&& toplev
&& !TREE_PUBLIC (decl))
|| DECL_COMDAT (decl))
{
/* Fool with the linkage according to #pragma interface. */
if (!interface_unknown)
/* Fool with the linkage of static consts according to #pragma
interface. */
if (!interface_unknown && !TREE_PUBLIC (decl))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = interface_only;
@ -8068,7 +8071,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
/* If a name was specified, get the string. */
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
asmspec = TREE_STRING_POINTER (asmspec_tree);
if (init && TREE_CODE (init) == NAMESPACE_DECL)
{

View file

@ -2210,8 +2210,12 @@ maybe_make_one_only (decl)
make_decl_one_only (decl);
if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl))
DECL_COMDAT (decl) = 1;
if (TREE_CODE (decl) == VAR_DECL)
{
DECL_COMDAT (decl) = 1;
/* Mark it needed so we don't forget to emit it. */
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;
}
}
/* Returns the virtual function with which the vtable for TYPE is

View file

@ -0,0 +1,18 @@
// Test that we don't emit unneeded copies of static data member template
// instantiations.
// Disable debug info so we don't get confused by the symbol name there.
// { dg-options "-g0" }
// { dg-final { scan-assembler-not "_ZN1AIiE1tE" } }
template <class T> struct A {
static const T t = 0;
};
template <class T> const T A<T>::t;
int i;
int main ()
{
i = A<int>::t; // Should just use the value
}

View file

@ -1935,16 +1935,24 @@ wrapup_global_declarations (vec, len)
to force a constant to be written if and only if it is
defined in a main file, as opposed to an include file. */
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& (((! TREE_READONLY (decl) || TREE_PUBLIC (decl))
&& !DECL_COMDAT (decl))
|| (!optimize
&& flag_keep_static_consts
&& !DECL_ARTIFICIAL (decl))
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
{
reconsider = 1;
rest_of_decl_compilation (decl, NULL, 1, 1);
bool needed = 1;
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
/* needed */;
else if (DECL_COMDAT (decl))
needed = 0;
else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl)
&& (optimize || !flag_keep_static_consts
|| DECL_ARTIFICIAL (decl)))
needed = 0;
if (needed)
{
reconsider = 1;
rest_of_decl_compilation (decl, NULL, 1, 1);
}
}
if (TREE_CODE (decl) == FUNCTION_DECL