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]
Other format: [Raw text]

[C++ PATCH] Fix parsing of pseudo-dtors in templates (PR c++/32384)


Hi!

If pseudo_expression in cp_parser_postfix_dot_deref_expression
is type dependent, then it is IMHO wrong to just assume it can't
be a pseudo-destructor.  The following patch tries to parse it in
that case as a pseudo-dtor and if the type after ~ is known to be
scalar, it will create PSEUDO_DTOR_EXPR (otherwise the parsing just
errors as that type can't be a class), otherwise will parse it
as before.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2007-10-31  Jakub Jelinek  <jakub@redhat.com>

	PR c++/32384
	* parser.c (cp_parser_postfix_dot_deref_expression): If
	POSTFIX_EXPRESSION is type dependent, try to parse it as pseudo dtor
	first and if that succeeds and type is SCALAR_TYPE_P, create
	PSEUDO_DTOR_EXPR.

	* g++.dg/template/pseudodtor1.C: New test.
	* g++.dg/template/pseudodtor2.C: New test.

--- gcc/cp/parser.c.jj	2007-10-31 11:21:31.000000000 +0100
+++ gcc/cp/parser.c	2007-10-31 13:25:39.000000000 +0100
@@ -4859,8 +4859,10 @@ cp_parser_postfix_dot_deref_expression (
   pseudo_destructor_p = false;
 
   /* If the SCOPE is a scalar type, then, if this is a valid program,
-     we must be looking at a pseudo-destructor-name.  */
-  if (scope && SCALAR_TYPE_P (scope))
+     we must be looking at a pseudo-destructor-name.  If POSTFIX_EXPRESSION
+     is type dependent, it can be pseudo-destructor-name or something else.
+     Try to parse it as pseudo-destructor-name first.  */
+  if ((scope && SCALAR_TYPE_P (scope)) || dependent_p)
     {
       tree s;
       tree type;
@@ -4869,7 +4871,12 @@ cp_parser_postfix_dot_deref_expression (
       /* Parse the pseudo-destructor-name.  */
       s = NULL_TREE;
       cp_parser_pseudo_destructor_name (parser, &s, &type);
-      if (cp_parser_parse_definitely (parser))
+      if (dependent_p
+	  && (cp_parser_error_occurred (parser)
+	      || TREE_CODE (type) != TYPE_DECL
+	      || !SCALAR_TYPE_P (TREE_TYPE (type))))
+	cp_parser_abort_tentative_parse (parser);
+      else if (cp_parser_parse_definitely (parser))
 	{
 	  pseudo_destructor_p = true;
 	  postfix_expression
--- gcc/testsuite/g++.dg/template/pseudodtor1.C.jj	2007-10-31 13:32:52.000000000 +0100
+++ gcc/testsuite/g++.dg/template/pseudodtor1.C	2007-10-31 13:31:55.000000000 +0100
@@ -0,0 +1,44 @@
+// PR c++/32384
+// { dg-do compile }
+
+struct A
+{
+  typedef int T;
+  T foo ();
+
+  A () { foo ().~T (); }
+};
+
+template<typename> struct B
+{
+  typedef int T;
+  T foo ();
+
+  B () { foo ().~T (); }
+};
+
+template<typename T> struct C
+{
+  T t;
+  C () { t.~T (); }
+};
+
+template<typename S> struct D
+{
+  typedef int T;
+  S foo ();
+
+  D () { foo ().~T(); }
+};
+
+struct Z
+{
+  Z () {}
+  ~Z () {}
+};
+
+A a;
+B<int> b;
+C<int> c1;
+C<Z> c2;
+D<int> d;
--- gcc/testsuite/g++.dg/template/pseudodtor2.C.jj	2007-10-31 13:33:44.000000000 +0100
+++ gcc/testsuite/g++.dg/template/pseudodtor2.C	2007-10-31 13:33:35.000000000 +0100
@@ -0,0 +1,18 @@
+// PR c++/32384
+// { dg-do compile }
+
+template<typename S> struct D
+{
+  typedef int T;
+  S foo ();
+
+  D () { foo ().~T(); }		// { dg-error "is not of type" }
+};
+
+struct Z
+{
+  Z () {}
+  ~Z () {}
+};
+
+D<Z> d;

	Jakub


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