This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH to avoid crashes on bogus destructors



This patch improves error-recovery for bogus destructor declarations.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

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.
	
Index: testsuite/g++.old-deja/g++.other/dtor3.C
===================================================================
RCS file: dtor3.C
diff -N dtor3.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- dtor3.C	Mon Sep 28 17:29:11 1998
***************
*** 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
+ }
+ 
+ 
+ 
Index: testsuite/g++.old-deja/g++.other/dtor4.C
===================================================================
RCS file: dtor4.C
diff -N dtor4.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- dtor4.C	Mon Sep 28 17:29:11 1998
***************
*** 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
+ };
Index: cp/decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.216
diff -c -p -r1.216 decl.c
*** decl.c	1998/09/25 11:07:29	1.216
--- decl.c	1998/09/28 22:40:25
*************** grokdeclarator (declarator, declspecs, d
*** 9553,9560 ****
  		      error ("destructor cannot be static member function");
  		    if (quals)
  		      {
! 			error ("destructors cannot be declared `const' or `volatile'");
! 			return void_type_node;
  		      }
  		    if (decl_context == FIELD)
  		      {
--- 9553,9561 ----
  		      error ("destructor cannot be static member function");
  		    if (quals)
  		      {
! 			cp_error ("destructors may not be `%s'",
! 				  IDENTIFIER_POINTER (TREE_VALUE (quals)));
! 			quals = NULL_TREE;
  		      }
  		    if (decl_context == FIELD)
  		      {
*************** grokdeclarator (declarator, declspecs, d
*** 9579,9586 ****
  		      }
  		    if (quals)
  		      {
! 			error ("constructors cannot be declared `const' or `volatile'");
! 			return void_type_node;
   		      }
  		    {
  		      RID_BIT_TYPE tmp_bits;
--- 9580,9588 ----
  		      }
  		    if (quals)
  		      {
! 			cp_error ("constructors may not be `%s'",
! 				  IDENTIFIER_POINTER (TREE_VALUE (quals)));
! 			quals = NULL_TREE;
   		      }
  		    {
  		      RID_BIT_TYPE tmp_bits;
*************** grokdeclarator (declarator, declspecs, d
*** 9638,9661 ****
  
  	    arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
  
! 	    if (declarator)
  	      {
! 		/* Get past destructors, etc.
! 		   We know we have one because FLAGS will be non-zero.
! 
! 		   Complain about improper parameter lists here.  */
  		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)
! 		      {
! 			error ("destructors cannot be specified with parameters");
! 			arg_types = void_list_node;
! 		      }
  		  }
  	      }
  
--- 9640,9661 ----
  
  	    arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
  
! 	    if (declarator && flags == DTOR_FLAG)
  	      {
! 		/* 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)
  		  {
! 		    cp_error ("destructors may not have parameters");
! 		    arg_types = void_list_node;
! 		    last_function_parms = NULL_TREE;
  		  }
  	      }
  
Index: cp/decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.136
diff -c -p -r1.136 decl2.c
*** decl2.c	1998/09/25 21:34:49	1.136
--- decl2.c	1998/09/28 22:40:39
*************** check_classfn (ctype, function)
*** 1464,1472 ****
  		  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.  */
  		  if (TREE_CODE (function) != TEMPLATE_DECL
  		      && TREE_CODE (fndecl) != TEMPLATE_DECL
  		      && (DECL_ASSEMBLER_NAME (function) 
  			  == DECL_ASSEMBLER_NAME (fndecl)))
  		    return fndecl;
--- 1464,1475 ----
  		  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.  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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]