From 40242ccfbdcd0a8951320221219e1b6e86cd3d7b Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Thu, 19 Aug 1999 08:06:17 +0000
Subject: [PATCH] cp-tree.def (PSEUDO_DTOR_EXPR): New tree code.

	* cp-tree.def (PSEUDO_DTOR_EXPR): New tree code.
	* decl2.c (build_expr_from_tree): Handle it.
	* error.c (dump_expr): Likewise.
	* pt.c (for_each_template_parm): Likewise.
	(tsubst_copy): Likewise.
	* tree.c (search_tree): Likewise.
	* semantics.c (finish_pseudo_destructor_call): Create it.

From-SVN: r28760
---
 gcc/cp/ChangeLog                            | 10 ++++++++++
 gcc/cp/cp-tree.def                          |  1 +
 gcc/cp/decl2.c                              |  6 ++++++
 gcc/cp/error.c                              |  8 ++++++++
 gcc/cp/pt.c                                 |  2 ++
 gcc/cp/semantics.c                          |  3 +++
 gcc/cp/tree.c                               |  1 +
 gcc/testsuite/g++.old-deja/g++.pt/crash48.C |  8 ++++++++
 8 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/crash48.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6e44c4fcf62d..443cdd5e9315 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+1999-08-19  Mark Mitchell  <mark@codesourcery.com>
+
+	* cp-tree.def (PSEUDO_DTOR_EXPR): New tree code.
+	* decl2.c (build_expr_from_tree): Handle it.
+	* error.c (dump_expr): Likewise.
+	* pt.c (for_each_template_parm): Likewise.
+	(tsubst_copy): Likewise.
+	* tree.c (search_tree): Likewise.
+	* semantics.c (finish_pseudo_destructor_call): Create it.
+	
 1999-08-18  Mark Mitchell  <mark@codesourcery.com>
 
 	* search.c (setup_class_bindings): Robustify.
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 19709222e469..d31d33ea85e4 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -214,6 +214,7 @@ DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
 DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
 DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", 'e', 2)
 DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1)
+DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3)
 
 DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
 DEFTREECODE (COMPOUND_STMT, "compound_stmt", 'e', 1)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a0a7e6c367fa..ecfdd61e695f 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3992,6 +3992,12 @@ build_expr_from_tree (t)
 	 build_expr_from_tree (TREE_OPERAND (t, 1)),
 	 build_expr_from_tree (TREE_OPERAND (t, 2)));
 
+    case PSEUDO_DTOR_EXPR:
+      return (finish_pseudo_destructor_call_expr 
+	      (build_expr_from_tree (TREE_OPERAND (t, 0)),
+	       build_expr_from_tree (TREE_OPERAND (t, 1)),
+	       build_expr_from_tree (TREE_OPERAND (t, 2))));
+
     case TREE_LIST:
       {
 	tree purpose, value, chain;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ce0ffbf11b66..b6598ff30a4b 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1776,6 +1776,14 @@ dump_expr (t, nop)
       dump_expr (TREE_OPERAND (t, 0), nop);
       break;
 
+    case PSEUDO_DTOR_EXPR:
+      dump_expr (TREE_OPERAND (t, 2), nop);
+      OB_PUTS (".");
+      dump_type (TREE_OPERAND (t, 0), nop);
+      OB_PUTS ("::~");
+      dump_type (TREE_OPERAND (t, 1), nop);
+      break;
+
     case TEMPLATE_ID_EXPR:
       dump_decl (t, 0);
       break;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9a31d60699dd..e1e8ab435cc6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4300,6 +4300,7 @@ for_each_template_parm (t, fn, data)
     case DOTSTAR_EXPR:
     case TYPEID_EXPR:
     case LOOKUP_EXPR:
+    case PSEUDO_DTOR_EXPR:
       if (!fn)
 	return 1;
       /* Fall through.  */
@@ -7078,6 +7079,7 @@ tsubst_copy (t, args, complain, in_decl)
 
     case COND_EXPR:
     case MODOP_EXPR:
+    case PSEUDO_DTOR_EXPR:
       {
 	r = build_nt
 	  (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index dc6b54144b0c..def1276bffc4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1229,6 +1229,9 @@ finish_pseudo_destructor_call_expr (object, scope, destructor)
      tree scope;
      tree destructor;
 {
+  if (processing_template_decl)
+    return build_min_nt (PSEUDO_DTOR_EXPR, object, scope, destructor);
+
   if (scope && scope != destructor)
     cp_error ("destructor specifier `%T::~%T()' must have matching names", 
 	      scope, destructor);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d159ac143b37..8d367535ba06 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1675,6 +1675,7 @@ search_tree (t, func)
     case ARROW_EXPR:
     case DOTSTAR_EXPR:
     case TYPEID_EXPR:
+    case PSEUDO_DTOR_EXPR:
       break;
 
     case COMPLEX_CST:
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash48.C b/gcc/testsuite/g++.old-deja/g++.pt/crash48.C
new file mode 100644
index 000000000000..907360bf78e1
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash48.C
@@ -0,0 +1,8 @@
+// Build don't link:
+// Origin: Jean-Francois Panisset <panisset@discreet.com>
+
+template<class T>
+void foo(T *data)
+{
+  ((char *)data)->~T();
+}
-- 
GitLab