Blob Blame History Raw
2007-11-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/32241
	* pt.c (tsubst_copy_and_build) <case COMPONENT_REF>: If object_type
	is not scalar type, let finish_class_member_access_expr handle
	diagnostics.  Pass BIT_NOT_EXPR argument to
	finish_pseudo_destructor_expr.  Handle SCOPE_REF properly.

	* g++.dg/template/pseudodtor3.C: New test.

--- gcc/cp/pt.c	(revision 130065)
+++ gcc/cp/pt.c	(revision 130066)
@@ -11004,15 +11004,23 @@ tsubst_copy_and_build (tree t,
 
 	if (object_type && !CLASS_TYPE_P (object_type))
 	  {
-	    if (TREE_CODE (member) == BIT_NOT_EXPR)
-	      return finish_pseudo_destructor_expr (object,
-						    NULL_TREE,
-						    object_type);
-	    else if (TREE_CODE (member) == SCOPE_REF
-		     && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
-	      return finish_pseudo_destructor_expr (object,
-						    object,
-						    object_type);
+	    if (SCALAR_TYPE_P (object_type))
+	      {
+		tree s = NULL_TREE;
+		tree dtor = member;
+
+		if (TREE_CODE (dtor) == SCOPE_REF)
+		  {
+		    s = TREE_OPERAND (dtor, 0);
+		    dtor = TREE_OPERAND (dtor, 1);
+		  }
+		if (TREE_CODE (dtor) == BIT_NOT_EXPR)
+		  {
+		    dtor = TREE_OPERAND (dtor, 0);
+		    if (TYPE_P (dtor))
+		      return finish_pseudo_destructor_expr (object, s, dtor);
+		  }
+	      }
 	  }
 	else if (TREE_CODE (member) == SCOPE_REF
 		 && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
--- gcc/testsuite/g++.dg/template/pseudodtor3.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/pseudodtor3.C	(revision 130066)
@@ -0,0 +1,43 @@
+// PR c++/32241
+// { dg-do compile }
+
+struct A
+{
+  typedef int T;
+  T &foo ();
+  A () { foo.~T (); }	// { dg-error "does not have class type|expected" }
+};
+
+template <typename T> struct B
+{
+  T &foo ();
+  B () { foo.~T (); }	// { dg-error "invalid use of member" }
+};
+
+B<int> b;
+
+template <typename T, typename S> struct C
+{
+  T t;
+  C () { t.~S (); }	// { dg-error "is not of type" }
+};
+
+C<int, long int> c;
+
+template <typename T> struct D
+{
+  T t;
+  typedef long int U;
+  D () { t.~U (); }	// { dg-error "is not of type" }
+};
+
+D<int> d;
+
+template <typename T> struct E
+{
+  T &foo ();
+  typedef long int U;
+  E () { foo.~U (); }	// { dg-error "is not of type" }
+};
+
+E<int> e;