diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-08-11 22:13:32 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-08-11 22:13:32 +0000 |
commit | 2436b51feb8a5cf7ca694eb4bf13bcb1e6899217 (patch) | |
tree | 2147acebf7d4edadc9b4e0c586c723982b26e08f | |
parent | 5079843a2094412a6b25a23c1eeae4296d0ed15a (diff) | |
download | gcc-2436b51feb8a5cf7ca694eb4bf13bcb1e6899217.zip gcc-2436b51feb8a5cf7ca694eb4bf13bcb1e6899217.tar.gz gcc-2436b51feb8a5cf7ca694eb4bf13bcb1e6899217.tar.bz2 |
re PR c++/16964 (ICE in cp_parser_class_specifier due to redefinition)
PR c++/16964
* parser.c (cp_parser_class_specifier): Robustify.
PR c++/16904
* pt.c (tsubst_copy_and_build): Complain about invalid
qualification.
PR c++/16929
* pt.c (tsubst_default_argument): Clear out current_class_ptr and
current_class_ref while tsubsting.
PR c++/16964
* g++.dg/parse/error16.C: New test.
PR c++/16904
* g++.dg/template/error14.C: New test.
PR c++/16929
* g++.dg/template/error15.C: New test.
From-SVN: r85824
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/parser.c | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/error16.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/error14.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/error15.C | 24 |
7 files changed, 103 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 269b20b..d15b6fa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2004-08-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/16964 + * parser.c (cp_parser_class_specifier): Robustify. + + PR c++/16904 + * pt.c (tsubst_copy_and_build): Complain about invalid + qualification. + + PR c++/16929 + * pt.c (tsubst_default_argument): Clear out current_class_ptr and + current_class_ref while tsubsting. + 2004-08-10 Mark Mitchell <mark@codesourcery.com> PR c++/16971 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2176e05..65872c8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12308,6 +12308,7 @@ cp_parser_class_specifier (cp_parser* parser) bool nested_name_specifier_p; unsigned saved_num_template_parameter_lists; bool pop_p = false; + tree scope = NULL_TREE; push_deferring_access_checks (dk_no_deferred); @@ -12343,7 +12344,10 @@ cp_parser_class_specifier (cp_parser* parser) /* Start the class. */ if (nested_name_specifier_p) - pop_p = push_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type))); + { + scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)); + pop_p = push_scope (scope); + } type = begin_class_definition (type); if (type == error_mark_node) @@ -12368,7 +12372,7 @@ cp_parser_class_specifier (cp_parser* parser) if (type != error_mark_node) type = finish_struct (type, attributes); if (pop_p) - pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type))); + pop_scope (scope); /* If this class is not itself within the scope of another class, then we need to parse the bodies of all of the queued function definitions. Note that the queued functions defined in a class diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 14b0c83..0574f44 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5942,6 +5942,9 @@ tsubst_aggr_type (tree t, tree tsubst_default_argument (tree fn, tree type, tree arg) { + tree saved_class_ptr = NULL_TREE; + tree saved_class_ref = NULL_TREE; + /* This default argument came from a template. Instantiate the default argument here, not in tsubst. In the case of something like: @@ -5959,12 +5962,27 @@ tsubst_default_argument (tree fn, tree type, tree arg) within the scope of FN. Since push_access_scope sets current_function_decl, we must explicitly clear it here. */ current_function_decl = NULL_TREE; + /* The "this" pointer is not valid in a default argument. */ + if (cfun) + { + saved_class_ptr = current_class_ptr; + cp_function_chain->x_current_class_ptr = NULL_TREE; + saved_class_ref = current_class_ref; + cp_function_chain->x_current_class_ref = NULL_TREE; + } push_deferring_access_checks(dk_no_deferred); arg = tsubst_expr (arg, DECL_TI_ARGS (fn), tf_error | tf_warning, NULL_TREE); pop_deferring_access_checks(); + /* Restore the "this" pointer. */ + if (cfun) + { + cp_function_chain->x_current_class_ptr = saved_class_ptr; + cp_function_chain->x_current_class_ref = saved_class_ref; + } + pop_access_scope (fn); /* Make sure the default argument is reasonable. */ @@ -8495,6 +8513,21 @@ tsubst_copy_and_build (tree t, return error_mark_node; } } + else if (TREE_CODE (member) == SCOPE_REF + && !CLASS_TYPE_P (TREE_OPERAND (member, 0)) + && TREE_CODE (TREE_OPERAND (member, 0)) != NAMESPACE_DECL) + { + if (complain & tf_error) + { + if (TYPE_P (TREE_OPERAND (member, 0))) + error ("`%T' is not a class or namespace", + TREE_OPERAND (member, 0)); + else + error ("`%D' is not a class or namespace", + TREE_OPERAND (member, 0)); + } + return error_mark_node; + } else if (TREE_CODE (member) == FIELD_DECL) return finish_non_static_data_member (member, object, NULL_TREE); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c4226dc..9959a9d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2004-08-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/16964 + * g++.dg/parse/error16.C: New test. + + PR c++/16904 + * g++.dg/template/error14.C: New test. + + PR c++/16929 + * g++.dg/template/error15.C: New test. + 2004-08-11 Devang Patel <dpatel@apple.com> * gcc.dg/darwin-ld-20040809-1.c: New test. diff --git a/gcc/testsuite/g++.dg/parse/error16.C b/gcc/testsuite/g++.dg/parse/error16.C new file mode 100644 index 0000000..afc790e --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error16.C @@ -0,0 +1,8 @@ +// PR c++/16964 + +struct A +{ + struct B {}; // { dg-error "" } +}; + +struct A::B{}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error14.C b/gcc/testsuite/g++.dg/template/error14.C new file mode 100644 index 0000000..c5043cf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error14.C @@ -0,0 +1,8 @@ +// PR c++/16904 + +template<typename T> struct X +{ + X() { this->T::i; } // { dg-error "" } +}; + +X<int> x; diff --git a/gcc/testsuite/g++.dg/template/error15.C b/gcc/testsuite/g++.dg/template/error15.C new file mode 100644 index 0000000..5a1a322 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error15.C @@ -0,0 +1,24 @@ +// PR c++/16929 + +template <class T> +class A { + int x; +}; + +template <class T> +class B { +protected: + + A<T> a; // { dg-error "" } + + void f(const A<T> * a1 = &a); + + void g(void); +}; + +template <class T> +void B<T>::g(void) { + f(); // { dg-error "" } +} + +template class B<long>; // { dg-error "" } |