OSDN Git Service

* toplev.c (wrapup_global_declarations): Clarify variable handling.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Mar 2002 09:54:42 +0000 (09:54 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Mar 2002 09:54:42 +0000 (09:54 +0000)
        -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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50802 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/testsuite/g++.dg/abi/vague1.C [new file with mode: 0644]
gcc/toplev.c

index a1f9c16..dfe2c0a 100644 (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.
index 2c9b1e5..4608f11 100644 (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.
index a1f128f..758524b 100644 (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))
-    {
-      /* 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)
     {
index 8841dec..5246a7f 100644 (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
diff --git a/gcc/testsuite/g++.dg/abi/vague1.C b/gcc/testsuite/g++.dg/abi/vague1.C
new file mode 100644 (file)
index 0000000..928d652
--- /dev/null
@@ -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
+}
index fa8af75..5ea36ae 100644 (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