aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-09-28 17:34:33 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-09-28 17:34:33 +0000
commit4f70a8465393270fe9bafe6b15fb8547e54c2e8c (patch)
tree887de5f00917ddfd4504ab6c1955e53e99690cc7
parentab339d62c08bbac39c8f06a6daa0bcfc9acdf0a7 (diff)
downloadgcc-4f70a8465393270fe9bafe6b15fb8547e54c2e8c.zip
gcc-4f70a8465393270fe9bafe6b15fb8547e54c2e8c.tar.gz
gcc-4f70a8465393270fe9bafe6b15fb8547e54c2e8c.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c38
-rw-r--r--gcc/cp/decl2.c5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/dtor3.C51
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/dtor4.C31
5 files changed, 112 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0794116..2bc04c9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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>
* search.c (get_base_distance): Remove assert.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index abd0808..582bd66 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9553,8 +9553,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
error ("destructor cannot be static member function");
if (quals)
{
- error ("destructors cannot be declared `const' or `volatile'");
- return void_type_node;
+ cp_error ("destructors may not be `%s'",
+ IDENTIFIER_POINTER (TREE_VALUE (quals)));
+ quals = NULL_TREE;
}
if (decl_context == FIELD)
{
@@ -9579,8 +9580,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
if (quals)
{
- error ("constructors cannot be declared `const' or `volatile'");
- return void_type_node;
+ cp_error ("constructors may not be `%s'",
+ IDENTIFIER_POINTER (TREE_VALUE (quals)));
+ quals = NULL_TREE;
}
{
RID_BIT_TYPE tmp_bits;
@@ -9638,24 +9640,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
- if (declarator)
+ if (declarator && flags == DTOR_FLAG)
{
- /* Get past destructors, etc.
- We know we have one because FLAGS will be non-zero.
-
- Complain about improper parameter lists here. */
+ /* A destructor declared in the body of a class will
+ be represented as a BIT_NOT_EXPR. But, we just
+ want the underlying IDENTIFIER. */
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);
-
- if (strict_prototype == 0 && arg_types == 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;
- }
+ cp_error ("destructors may not have parameters");
+ arg_types = void_list_node;
+ last_function_parms = NULL_TREE;
}
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 7faaf55..34d2c93 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1464,9 +1464,12 @@ check_classfn (ctype, function)
fndecl = OVL_CURRENT (fndecls);
/* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is
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
&& TREE_CODE (fndecl) != TEMPLATE_DECL
+ && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
&& (DECL_ASSEMBLER_NAME (function)
== DECL_ASSEMBLER_NAME (fndecl)))
return fndecl;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/dtor3.C b/gcc/testsuite/g++.old-deja/g++.other/dtor3.C
new file mode 100644
index 0000000..a2ad16d
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/dtor3.C
@@ -0,0 +1,51 @@
+// 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
+}
+
+
+
diff --git a/gcc/testsuite/g++.old-deja/g++.other/dtor4.C b/gcc/testsuite/g++.old-deja/g++.other/dtor4.C
new file mode 100644
index 0000000..f23ab78
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/dtor4.C
@@ -0,0 +1,31 @@
+// 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
+};