* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103806
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
&& (!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
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.
}
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));
{
/* 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. */
/* 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;
}
+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
--- /dev/null
+// 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;
+};