diff options
author | Jason Merrill <jason@redhat.com> | 2002-03-15 04:54:42 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2002-03-15 04:54:42 -0500 |
commit | 5cc90635da0173defc0f186265a68913ca5f21b0 (patch) | |
tree | de143ae82ad2ce9277bf578207642918da268945 /gcc | |
parent | 0f9b56dcb2d761010137a566c2af9bf98d8f14eb (diff) | |
download | gcc-5cc90635da0173defc0f186265a68913ca5f21b0.zip gcc-5cc90635da0173defc0f186265a68913ca5f21b0.tar.gz gcc-5cc90635da0173defc0f186265a68913ca5f21b0.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 29 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/vague1.C | 18 | ||||
-rw-r--r-- | gcc/toplev.c | 26 |
6 files changed, 68 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1f9c16f..dfe2c0a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c9b1e5..4608f11 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a1f128f..758524b 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)) - { - /* Fool with the linkage according to #pragma interface. */ - if (!interface_unknown) + /* 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 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 8841dec..5246a7f 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 0000000..928d652 --- /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 <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 +} diff --git a/gcc/toplev.c b/gcc/toplev.c index fa8af75..5ea36ae 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 |