From 5cc90635da0173defc0f186265a68913ca5f21b0 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 15 Mar 2002 04:54:42 -0500 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/cp/ChangeLog | 6 ++++++ gcc/cp/decl.c | 27 +++++++++++++++------------ gcc/cp/decl2.c | 8 ++++++-- gcc/testsuite/g++.dg/abi/vague1.C | 18 ++++++++++++++++++ gcc/toplev.c | 26 +++++++++++++++++--------- 6 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/vague1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1f9c16f420..dfe2c0a2b7e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-03-15 Jason Merrill + + * toplev.c (wrapup_global_declarations): Clarify variable handling. + -fkeep-static-consts doesn't apply to comdats. + 2002-03-14 Richard Henderson * c-decl.c: Include c-pragma.h. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c9b1e55df2..4608f11e8e9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2002-03-15 Jason Merrill + + * 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 * decl.c: Include c-pragma.h. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a1f128ff95c..758524b7c75 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 8841dec2e2b..5246a7f019a 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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 diff --git a/gcc/testsuite/g++.dg/abi/vague1.C b/gcc/testsuite/g++.dg/abi/vague1.C new file mode 100644 index 00000000000..928d652b836 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/vague1.C @@ -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 struct A { + static const T t = 0; +}; + +template const T A::t; + +int i; +int main () +{ + i = A::t; // Should just use the value +} diff --git a/gcc/toplev.c b/gcc/toplev.c index fa8af755fdb..5ea36ae182c 100644 --- a/gcc/toplev.c +++ b/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