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:
parent
0f9b56dcb2
commit
5cc90635da
6 changed files with 67 additions and 23 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
18
gcc/testsuite/g++.dg/abi/vague1.C
Normal file
18
gcc/testsuite/g++.dg/abi/vague1.C
Normal 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
|
||||
}
|
26
gcc/toplev.c
26
gcc/toplev.c
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue