aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c29
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/testsuite/g++.dg/abi/vague1.C18
-rw-r--r--gcc/toplev.c26
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