Commit 4f70a846 by Mark Mitchell Committed by Mark Mitchell

decl.c (grokdeclarator): Tighten checks for invalid destructors.

	* decl.c (grokdeclarator): Tighten checks for invalid
	destructors.  Improve error-messages and error-recovery.
	* decl2.c (check_classfn): Don't assume that mangled destructor
	names contain type information.

From-SVN: r22630
parent ab339d62
1998-09-28 Mark Mitchell <mark@markmitchell.com>
* decl.c (grokdeclarator): Tighten checks for invalid
destructors. Improve error-messages and error-recovery.
* decl2.c (check_classfn): Don't assume that mangled destructor
names contain type information.
1998-09-25 Jason Merrill <jason@yorick.cygnus.com> 1998-09-25 Jason Merrill <jason@yorick.cygnus.com>
* search.c (get_base_distance): Remove assert. * search.c (get_base_distance): Remove assert.
......
...@@ -9553,8 +9553,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9553,8 +9553,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
error ("destructor cannot be static member function"); error ("destructor cannot be static member function");
if (quals) if (quals)
{ {
error ("destructors cannot be declared `const' or `volatile'"); cp_error ("destructors may not be `%s'",
return void_type_node; IDENTIFIER_POINTER (TREE_VALUE (quals)));
quals = NULL_TREE;
} }
if (decl_context == FIELD) if (decl_context == FIELD)
{ {
...@@ -9579,8 +9580,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9579,8 +9580,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
} }
if (quals) if (quals)
{ {
error ("constructors cannot be declared `const' or `volatile'"); cp_error ("constructors may not be `%s'",
return void_type_node; IDENTIFIER_POINTER (TREE_VALUE (quals)));
quals = NULL_TREE;
} }
{ {
RID_BIT_TYPE tmp_bits; RID_BIT_TYPE tmp_bits;
...@@ -9638,24 +9640,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9638,24 +9640,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0); arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
if (declarator) if (declarator && flags == DTOR_FLAG)
{ {
/* Get past destructors, etc. /* A destructor declared in the body of a class will
We know we have one because FLAGS will be non-zero. be represented as a BIT_NOT_EXPR. But, we just
want the underlying IDENTIFIER. */
Complain about improper parameter lists here. */
if (TREE_CODE (declarator) == BIT_NOT_EXPR) if (TREE_CODE (declarator) == BIT_NOT_EXPR)
declarator = TREE_OPERAND (declarator, 0);
if (strict_prototype == 0 && arg_types == NULL_TREE)
arg_types = void_list_node;
else if (arg_types == NULL_TREE
|| arg_types != void_list_node)
{ {
declarator = TREE_OPERAND (declarator, 0); cp_error ("destructors may not have parameters");
arg_types = void_list_node;
if (strict_prototype == 0 && arg_types == NULL_TREE) last_function_parms = NULL_TREE;
arg_types = void_list_node;
else if (arg_types == NULL_TREE
|| arg_types != void_list_node)
{
error ("destructors cannot be specified with parameters");
arg_types = void_list_node;
}
} }
} }
......
...@@ -1464,9 +1464,12 @@ check_classfn (ctype, function) ...@@ -1464,9 +1464,12 @@ check_classfn (ctype, function)
fndecl = OVL_CURRENT (fndecls); fndecl = OVL_CURRENT (fndecls);
/* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is
not mangled, so the check below does not work not mangled, so the check below does not work
correctly in that case. */ correctly in that case. Since mangled destructor names
do not include the type of the arguments, we
can't use this short-cut for them, either. */
if (TREE_CODE (function) != TEMPLATE_DECL if (TREE_CODE (function) != TEMPLATE_DECL
&& TREE_CODE (fndecl) != TEMPLATE_DECL && TREE_CODE (fndecl) != TEMPLATE_DECL
&& !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
&& (DECL_ASSEMBLER_NAME (function) && (DECL_ASSEMBLER_NAME (function)
== DECL_ASSEMBLER_NAME (fndecl))) == DECL_ASSEMBLER_NAME (fndecl)))
return fndecl; return fndecl;
......
// Build don't link:
struct S1
{
~S1(int); // ERROR - destructors may not have parameters
};
template <class T>
struct S2
{
~S2(int); // ERROR - destructors may not have parameters
};
struct S3
{
~S3(double) {} // ERROR - destructors may not have parameters
};
template <class T>
struct S4
{
~S4(double) {} // ERROR - destructors may not have parameters
};
struct S5
{
~S5();
};
S5::~S5(float)
{ // ERROR - destructors may not have parameters
}
template <class T>
struct S6
{
~S6();
};
template <class T>
S6<T>::~S6(float)
{ // ERROR - destructors may not have parameters
}
// Build don't link:
struct S1 {
~S1(); // ERROR - candidate
};
S1::~S1() const
{ // ERROR - prototype does not match
}
struct S2 {
~S2() volatile; // ERROR - destructors may not be volatile
};
template <class T>
struct S3 {
~S3(); // ERROR - candidate
};
template <class T>
S3<T>::~S3() volatile
{ // ERROR - prototype does not match
}
template <class T>
struct S4 {
~S4() const; // ERROR - destructors may not be const
};
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