re PR c++/23287 (Explicitly invoking destructor of template class in a template and...
authorJason Merrill <jason@redhat.com>
Mon, 19 Jan 2009 22:50:43 +0000 (17:50 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 19 Jan 2009 22:50:43 +0000 (17:50 -0500)
        PR c++/23287
        * parser.c (cp_parser_unqualified_id): In a template,
        accept ~identifier.
        * typeck.c (lookup_destructor): Handle IDENTIFIER_NODE.

From-SVN: r143502

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

index a58d4ac27d503ec28a89a136bb5379b0c94a75a0..5808ee5f7d88d624c627c772ad244779d782a5b2 100644 (file)
@@ -1,3 +1,10 @@
+2009-01-19  Jason Merrill  <jason@redhat.com>
+
+       PR c++/23287
+       * parser.c (cp_parser_unqualified_id): In a template,
+       accept ~identifier.
+       * typeck.c (lookup_destructor): Handle IDENTIFIER_NODE.
+
 2009-01-16  Jason Merrill  <jason@redhat.com>
 
        PR c++/38877
index 526a9a3acefbf3895a75484f790fd2344eccd1a6..5baf5f55196fd34aa0cf6d37e0726d2c10f3e500 100644 (file)
@@ -3880,6 +3880,8 @@ cp_parser_unqualified_id (cp_parser* parser,
            parser->scope = NULL_TREE;
            parser->object_scope = NULL_TREE;
            parser->qualifying_scope = NULL_TREE;
+           if (processing_template_decl)
+             cp_parser_parse_tentatively (parser);
            type_decl
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
@@ -3888,6 +3890,14 @@ cp_parser_unqualified_id (cp_parser* parser,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
+           if (processing_template_decl
+               && ! cp_parser_parse_definitely (parser))
+             {
+               /* We couldn't find a type with this name, so just accept
+                  it and check for a match at instantiation time.  */
+               type_decl = cp_parser_identifier (parser);
+               return build_nt (BIT_NOT_EXPR, type_decl);
+             }
          }
        /* If an error occurred, assume that the name of the
           destructor is the same as the name of the qualifying
index 415b8a26291f3e862a435ef69a0d4d0724fd1cfb..6c69256aa39976114ee76662e20462b87611adba 100644 (file)
@@ -2101,8 +2101,8 @@ build_class_member_access_expr (tree object, tree member,
   return result;
 }
 
-/* Return the destructor denoted by OBJECT.SCOPE::~DTOR_NAME, or, if
-   SCOPE is NULL, by OBJECT.~DTOR_NAME.  */
+/* Return the destructor denoted by OBJECT.SCOPE::DTOR_NAME, or, if
+   SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type.  */
 
 static tree
 lookup_destructor (tree object, tree scope, tree dtor_name)
@@ -2117,7 +2117,21 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
             scope, dtor_type);
       return error_mark_node;
     }
-  if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
+  if (TREE_CODE (dtor_type) == IDENTIFIER_NODE)
+    {
+      /* In a template, names we can't find a match for are still accepted
+        destructor names, and we check them here.  */
+      if (check_dtor_name (object_type, dtor_type))
+       dtor_type = object_type;
+      else
+       {
+         error ("object type %qT does not match destructor name ~%qT",
+                object_type, dtor_type);
+         return error_mark_node;
+       }
+      
+    }
+  else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
     {
       error ("the type being destroyed is %qT, but the destructor refers to %qT",
             TYPE_MAIN_VARIANT (object_type), dtor_type);
index bbe897580dde30e65bf9470bda98c6cebd67d5d8..e9bfcd25dea8ddcbd27c7b28c531b0397d36095f 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-19  Jason Merrill  <jason@redhat.com>
+
+       PR c++/23287
+       * g++.dg/template/dtor5.C: New test.
+
 2009-01-19  Mikael Morin  <mikael.morin@tele2.fr>
 
        PR fortran/38859
diff --git a/gcc/testsuite/g++.dg/template/dtor5.C b/gcc/testsuite/g++.dg/template/dtor5.C
new file mode 100644 (file)
index 0000000..8fa4eeb
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/23287
+
+template <class T> struct A
+{
+  int i;
+  ~A();
+}; 
+
+template <class T> void f(A<T> *ap) {
+  ap->~A(); 
+} 
+
+template <class T> void g(A<T> *ap) {
+  ap->~B();                    // { dg-error "destructor name" }
+} 
+
+int main()
+{
+  f(new A<int>);
+  g(new A<int>);
+}