re PR c++/23699 (rejects static int as non constant after "extern template")
authorMark Mitchell <mark@codesourcery.com>
Sat, 3 Sep 2005 18:18:48 +0000 (18:18 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 3 Sep 2005 18:18:48 +0000 (18:18 +0000)
PR c++/23699
* decl2.c (mark_used): Always instantiate static data members
initialized by constant expressions.
* pt.c (instantiate_decl): Instantiate the initializers for static
data members initialized by constant expressions.

PR c++/21687
* semantics.c (expand_or_defer_fn): Do not call ggc_collect when
finishing processing for a template function in a local class.
Revert:
2005-09-02  Mark Mitchell  <mark@codesourcery.com>
* parser.c (cp_parser_class_specifier): Push/pop GC contexts
around functions in local classes.

PR c++/23699
* g++.dg/ext/static1.C: New test.

From-SVN: r103806

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/static1.C [new file with mode: 0644]

index 69e62c4..e9d3b2b 100644 (file)
@@ -1,3 +1,19 @@
+2005-09-03  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/23699
+       * decl2.c (mark_used): Always instantiate static data members
+       initialized by constant expressions.
+       * pt.c (instantiate_decl): Instantiate the initializers for static
+       data members initialized by constant expressions.
+
+       PR c++/21687
+       * semantics.c (expand_or_defer_fn): Do not call ggc_collect when
+       finishing processing for a template function in a local class.
+       Revert:
+       2005-09-02  Mark Mitchell  <mark@codesourcery.com>
+       * parser.c (cp_parser_class_specifier): Push/pop GC contexts
+       around functions in local classes.
+
 2005-09-02  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/21687
index 3821ab0..75ec65f 100644 (file)
@@ -3270,7 +3270,12 @@ mark_used (tree decl)
       && (!DECL_EXPLICIT_INSTANTIATION (decl)
          || (TREE_CODE (decl) == FUNCTION_DECL
              && DECL_INLINE (DECL_TEMPLATE_RESULT
-                             (template_for_substitution (decl))))))
+                             (template_for_substitution (decl))))
+         /* We need to instantiate static data members so that there
+            initializers are available in integral constant
+            expressions.  */
+         || (TREE_CODE (decl) == VAR_DECL
+             && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))))
     /* We put off instantiating functions in order to improve compile
        times.  Maintaining a stack of active functions is expensive,
        and the inliner knows to instantiate any functions it might
index f066403..6feb114 100644 (file)
@@ -12673,9 +12673,6 @@ cp_parser_class_specifier (cp_parser* parser)
       tree fn;
       tree class_type = NULL_TREE;
       tree pushed_scope = NULL_TREE;
-      /* True if we have called ggc_push_context, and therefore need
-        to make a matching call to ggc_pop_context.  */
-      bool need_ggc_pop_context;
  
       /* In a first pass, parse default arguments to the functions.
         Then, in a second pass, parse the bodies of the functions.
@@ -12712,7 +12709,6 @@ cp_parser_class_specifier (cp_parser* parser)
        }
       if (pushed_scope)
        pop_scope (pushed_scope);
-      need_ggc_pop_context = false;
       /* Now parse the body of the functions.  */
       for (TREE_VALUE (parser->unparsed_functions_queues)
             = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
@@ -12722,21 +12718,9 @@ cp_parser_class_specifier (cp_parser* parser)
        {
          /* Figure out which function we need to process.  */
          fn = TREE_VALUE (queue_entry);
-         /* We call ggc_collect after processing a function body in
-            order to clean up garbage generated.  If we're processing
-            a local class, however, then we must not clean up stuff
-            from the function containing the class, so we have to
-            push a new garbage-collection context.  */
-         if (function_depth && !need_ggc_pop_context)
-           {
-             need_ggc_pop_context = true;
-             ggc_push_context ();
-           }
          /* Parse the function.  */
          cp_parser_late_parsing_for_member (parser, fn);
        }
-      if (need_ggc_pop_context)
-       ggc_pop_context ();
     }
 
   /* Put back any saved access checks.  */
index 528d8b7..dbdf74d 100644 (file)
@@ -3044,8 +3044,11 @@ expand_or_defer_fn (tree fn)
       /* Normally, collection only occurs in rest_of_compilation.  So,
         if we don't collect here, we never collect junk generated
         during the processing of templates until we hit a
-        non-template function.  */
-      ggc_collect ();
+        non-template function.  It's not safe to do this inside a
+        nested class, though, as the parser may have local state that
+        is not a GC root.  */
+      if (!function_depth)
+       ggc_collect ();
       return;
     }
 
index ab29708..0abc44f 100644 (file)
@@ -1,3 +1,8 @@
+2005-09-03  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/23699
+       * g++.dg/ext/static1.C: New test.
+
 2005-09-02  Richard Henderson  <rth@redhat.com>
 
        * gcc.c-torture/execute/frame-address.c (check_fa_mid): Avoid
diff --git a/gcc/testsuite/g++.dg/ext/static1.C b/gcc/testsuite/g++.dg/ext/static1.C
new file mode 100644 (file)
index 0000000..9298b1d
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/23699
+// { dg-options "" }
+
+template<typename _CharT > class basic_string;
+typedef basic_string<char> string;
+template<typename _CharT>
+struct basic_string
+{
+  static const int npos = -1;
+};
+template<typename _CharT>
+const int basic_string<_CharT>::npos;
+
+extern template class basic_string<char>;
+struct A
+{
+  static const long npos = string::npos;
+};