Well, this one has been around for a while.

this->X::~X() is handled by finish_class_member_access_expr and its
lookup_destructor subroutine; let's use it in cp_parser_lookup_name for the
case where this-> is implicit.

Tested x86_64-pc-linux-gnu, applying to trunk.

        * parser.c (cp_parser_lookup_name): Use lookup_destructor.
        * typeck.c (lookup_destructor): No longer static.
---
 gcc/cp/cp-tree.h                    |  1 +
 gcc/cp/parser.c                     |  5 +++++
 gcc/cp/typeck.c                     |  3 +--
 gcc/testsuite/g++.dg/lookup/dtor1.C | 13 +++++++++++++
 gcc/testsuite/g++.dg/parse/dtor3.C  |  8 ++++----
 5 files changed, 24 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lookup/dtor1.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b47698e1d0c..c35ed9abe08 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7500,6 +7500,7 @@ extern tree build_class_member_access_expr      (cp_expr, 
tree, tree, bool,
                                                 tsubst_flags_t);
 extern tree finish_class_member_access_expr     (cp_expr, tree, bool,
                                                 tsubst_flags_t);
+extern tree lookup_destructor                  (tree, tree, tree, 
tsubst_flags_t);
 extern tree build_x_indirect_ref               (location_t, tree,
                                                 ref_operator,
                                                 tsubst_flags_t);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 16d1359c47d..a1816e8ace7 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -27918,6 +27918,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
       if (!type || !CLASS_TYPE_P (type))
        return error_mark_node;
 
+      /* In a non-static member function, check implicit this->.  */
+      if (current_class_ref)
+       return lookup_destructor (current_class_ref, parser->scope, name,
+                                 tf_warning_or_error);
+
       if (CLASSTYPE_LAZY_DESTRUCTOR (type))
        lazily_declare_fn (sfk_destructor, type);
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d3814585e3f..669ca83cccf 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -59,7 +59,6 @@ static tree get_delta_difference (tree, tree, bool, bool, 
tsubst_flags_t);
 static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
 static bool casts_away_constness (tree, tree, tsubst_flags_t);
 static bool maybe_warn_about_returning_address_of_local (tree);
-static tree lookup_destructor (tree, tree, tree, tsubst_flags_t);
 static void error_args_num (location_t, tree, bool);
 static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
                               tsubst_flags_t);
@@ -2696,7 +2695,7 @@ build_class_member_access_expr (cp_expr object, tree 
member,
 /* 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
+tree
 lookup_destructor (tree object, tree scope, tree dtor_name,
                   tsubst_flags_t complain)
 {
diff --git a/gcc/testsuite/g++.dg/lookup/dtor1.C 
b/gcc/testsuite/g++.dg/lookup/dtor1.C
new file mode 100644
index 00000000000..29122876401
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/dtor1.C
@@ -0,0 +1,13 @@
+// PR c++/12333
+
+struct A { };
+
+struct X { 
+  void f () {
+    X::~X ();
+    this->~X();
+    ~X();                      // { dg-error "" "unary ~" }
+    A::~A ();                  // { dg-error "" }
+    X::~A ();                          // { dg-error "" }
+  }
+};
diff --git a/gcc/testsuite/g++.dg/parse/dtor3.C 
b/gcc/testsuite/g++.dg/parse/dtor3.C
index 3041ae4a568..6121bed7e8b 100644
--- a/gcc/testsuite/g++.dg/parse/dtor3.C
+++ b/gcc/testsuite/g++.dg/parse/dtor3.C
@@ -4,13 +4,13 @@
 //  destructor call.
 
 struct Y { 
-  ~Y() {}      // { dg-bogus "note" "implemented DR272" { xfail *-*-* } }  
+  ~Y() {}      // { dg-bogus "note" "implemented DR272" }  
 };
 
 struct X : Y { 
-  ~X() {}      // { dg-bogus "note" "implemented DR272" { xfail *-*-* } }  
+  ~X() {}      // { dg-bogus "note" "implemented DR272" }  
   void f() { 
-    X::~X();   // { dg-bogus "" "implemented DR272" { xfail *-*-* } }  
-    Y::~Y();   // { dg-bogus "" "implemented DR272" { xfail *-*-* } }  
+    X::~X();   // { dg-bogus "" "implemented DR272" }  
+    Y::~Y();   // { dg-bogus "" "implemented DR272" }  
   } 
 };

base-commit: 6e8f413c4dc0dc14eec025c1ab21757d88b7b352
-- 
2.18.1

Reply via email to