decl.c (grokdeclarator): Tighten checks for invalid destructors.
authorMark Mitchell <mark@markmitchell.com>
Mon, 28 Sep 1998 17:34:33 +0000 (17:34 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 28 Sep 1998 17:34:33 +0000 (17:34 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/testsuite/g++.old-deja/g++.other/dtor3.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dtor4.C [new file with mode: 0644]

index 07941166e8e730ef1564e981b8fcb101c1aea1b8..2bc04c9dab64ad5334d5b92819b5bd9fb1ef6189 100644 (file)
@@ -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.
index abd0808e485b6ea094032540461e53acc9bc91db..582bd66488a81f668397a26e5256f35914a3423c 100644 (file)
@@ -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;
                  }
              }
 
index 7faaf5546cffcfda29e82134e790e2c633df44ed..34d2c93617fa879b12da693ebe50dbed5f7f69ee 100644 (file)
@@ -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 (file)
index 0000000..a2ad16d
--- /dev/null
@@ -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 (file)
index 0000000..f23ab78
--- /dev/null
@@ -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
+};