aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
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 /gcc/cp/pt.c
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
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c33
1 files changed, 33 insertions, 0 deletions
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);