diff options
author | Mark Mitchell <mark@markmitchell.com> | 1998-09-28 17:34:33 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-09-28 17:34:33 +0000 |
commit | 4f70a8465393270fe9bafe6b15fb8547e54c2e8c (patch) | |
tree | 887de5f00917ddfd4504ab6c1955e53e99690cc7 | |
parent | ab339d62c08bbac39c8f06a6daa0bcfc9acdf0a7 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 38 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/dtor3.C | 51 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/dtor4.C | 31 |
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 +}; |