re PR c++/33094 (ICE on valid C++ virtual template static member in anonymous namespace)
authorJason Merrill <jason@redhat.com>
Sun, 30 Sep 2007 02:41:39 +0000 (22:41 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 30 Sep 2007 02:41:39 +0000 (22:41 -0400)
        PR c++/33094
        * decl.c (make_rtl_for_nonlocal_decl): It's ok for a member
        constant to not have DECL_EXTERNAL if it's file-local.

From-SVN: r128890

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/testsuite/g++.dg/ext/visibility/anon6.C [new file with mode: 0644]

index 5827a57..5609f1a 100644 (file)
@@ -1,3 +1,9 @@
+2007-09-29  Jason Merrill  <jason@redhat.com>
+
+       PR c++/33094
+       * decl.c (make_rtl_for_nonlocal_decl): It's ok for a member 
+       constant to not have DECL_EXTERNAL if it's file-local.
+
 2007-09-28  Ollie Wild  <aaw@google.com>
 
        Revert
index f28e965..bd9292a 100644 (file)
@@ -3225,7 +3225,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
 /* DECL_EXTERNAL must be set on a decl until the decl is actually emitted,
    so that assemble_external will work properly.  So we have this flag to
-   tell us whether the decl is really not external.  */
+   tell us whether the decl is really not external.
+
+   This flag does not indicate whether or not the decl is defined in the
+   current translation unit; it indicates whether or not we should emit the
+   decl at the end of compilation if it is defined and needed.  */
 #define DECL_NOT_REALLY_EXTERN(NODE) \
   (DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern)
 
index b898a02..469e6b8 100644 (file)
@@ -5092,7 +5092,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
       /* An in-class declaration of a static data member should be
         external; it is only a declaration, and not a definition.  */
       if (init == NULL_TREE)
-       gcc_assert (DECL_EXTERNAL (decl));
+       gcc_assert (DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl));
     }
 
   /* We don't create any RTL for local variables.  */
index c00c979..ce5e528 100644 (file)
@@ -1314,6 +1314,9 @@ coerce_delete_type (tree type)
   return type;
 }
 \f
+/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable
+   and mark them as needed.  */
+
 static void
 mark_vtable_entries (tree decl)
 {
diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon6.C b/gcc/testsuite/g++.dg/ext/visibility/anon6.C
new file mode 100644 (file)
index 0000000..951de49
--- /dev/null
@@ -0,0 +1,28 @@
+// PR c++/33094
+// { dg-final { scan-assembler "1BIiE1cE" } }
+// { dg-final { scan-assembler-not "globl.*1BIiE1cE" } }
+// { dg-final { scan-assembler-not "1CIiE1cE" } }
+
+// Test that B<int>::c is emitted as an internal symbol, and C<int>::c is
+// not emitted.
+
+namespace
+{
+  template <typename T>
+  class A
+  {
+    virtual T f1() { return c; }
+    static const T c = 0;
+  };
+
+  template <typename T>
+  class B
+  {
+    static const T c = 0;
+  };
+
+  template <typename T> const T B<T>::c;
+
+  template class A<int>;
+  template class B<int>;
+}