aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-09-03 18:18:48 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-09-03 18:18:48 +0000
commit2725073463dfe4d70a5111f6723a2f4ea36ba875 (patch)
treece48d74b7c9e2e53dacefc8aad93e808cce4796a
parent7c95bbfbddcdadec7ca9f7662f55c74159064107 (diff)
downloadgcc-2725073463dfe4d70a5111f6723a2f4ea36ba875.zip
gcc-2725073463dfe4d70a5111f6723a2f4ea36ba875.tar.gz
gcc-2725073463dfe4d70a5111f6723a2f4ea36ba875.tar.bz2
re PR c++/23699 (rejects static int as non constant after "extern template")
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
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/decl2.c7
-rw-r--r--gcc/cp/parser.c16
-rw-r--r--gcc/cp/semantics.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/static1.C18
6 files changed, 50 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 69e62c4..e9d3b2b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 3821ab0..75ec65f 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f066403..6feb114 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 528d8b7..dbdf74d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ab29708..0abc44f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..9298b1d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/static1.C
@@ -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;
+};