OSDN Git Service

PR c++/32384
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Nov 2007 22:54:39 +0000 (22:54 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Nov 2007 22:54:39 +0000 (22:54 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129836 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/pseudodtor1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/pseudodtor2.C [new file with mode: 0644]

index c7946ac..51f219b 100644 (file)
@@ -1,5 +1,11 @@
 2007-11-01  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.
+
        PR c++/32260
        * rtti.c (enum_tinfo_kind): Fix TK_TYPE_INFO_TYPE comment.
        (typeid_ok_p): Use the same alias set for abi::__type_info_pseudo
index 2b73a85..7734cc1 100644 (file)
@@ -4850,8 +4850,10 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
   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;
@@ -4860,7 +4862,12 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
       /* 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
index 74c7230..849f07e 100644 (file)
@@ -1,5 +1,9 @@
 2007-11-01  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/32384
+       * g++.dg/template/pseudodtor1.C: New test.
+       * g++.dg/template/pseudodtor2.C: New test.
+
        PR c++/32260
        * g++.dg/rtti/typeid7.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/template/pseudodtor1.C b/gcc/testsuite/g++.dg/template/pseudodtor1.C
new file mode 100644 (file)
index 0000000..cf7c254
--- /dev/null
@@ -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;
diff --git a/gcc/testsuite/g++.dg/template/pseudodtor2.C b/gcc/testsuite/g++.dg/template/pseudodtor2.C
new file mode 100644 (file)
index 0000000..796aff0
--- /dev/null
@@ -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;