aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-08-11 22:13:32 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-08-11 22:13:32 +0000
commit2436b51feb8a5cf7ca694eb4bf13bcb1e6899217 (patch)
tree2147acebf7d4edadc9b4e0c586c723982b26e08f
parent5079843a2094412a6b25a23c1eeae4296d0ed15a (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/cp/parser.c8
-rw-r--r--gcc/cp/pt.c33
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/parse/error16.C8
-rw-r--r--gcc/testsuite/g++.dg/template/error14.C8
-rw-r--r--gcc/testsuite/g++.dg/template/error15.C24
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 "" }