Commit 2436b51f by Mark Mitchell Committed by Mark Mitchell

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
parent 5079843a
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
......
......@@ -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
......
......@@ -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);
......
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.
......
// PR c++/16964
struct A
{
struct B {}; // { dg-error "" }
};
struct A::B{}; // { dg-error "" }
// PR c++/16904
template<typename T> struct X
{
X() { this->T::i; } // { dg-error "" }
};
X<int> x;
// 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 "" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment