[PATCH] D25817: [Sema] Improve the error diagnostic for dot destructor calls on pointer objects

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 20 03:13:00 PDT 2016


arphaman created this revision.
arphaman added reviewers: dblaikie, majnemer.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This patch improves the mismatched destructor type error by detecting when the destructor call has used a '.' instead of a '->' on a pointer to the destructed type.

For example, when given the code sample below:

  struct Bar {
    ~Bar();
  };
  void bar(Bar *object) {
    object.~Bar();
  }

Clang will now produce the following diagnostic: `error: member reference type 'Bar *' is a pointer; did you mean to use '->'?`.


Repository:
  rL LLVM

https://reviews.llvm.org/D25817

Files:
  lib/Sema/SemaExprCXX.cpp
  test/CXX/special/class.dtor/p10-0x.cpp
  test/SemaCXX/pseudo-destructors.cpp


Index: test/SemaCXX/pseudo-destructors.cpp
===================================================================
--- test/SemaCXX/pseudo-destructors.cpp
+++ test/SemaCXX/pseudo-destructors.cpp
@@ -89,3 +89,26 @@
 void AliasTemplate(int *p) {
   p->~Id<int>();
 }
+
+namespace dotPointerAccess {
+struct Base {
+  virtual ~Base() {}
+};
+
+struct Derived : Base {
+  ~Derived() {}
+};
+
+void test() {
+  Derived d;
+  static_cast<Base *>(&d).~Base(); // expected-error {{member reference type 'dotPointerAccess::Base *' is a pointer; did you mean to use '->'}}
+  d->~Derived(); // expected-error {{member reference type 'dotPointerAccess::Derived' is not a pointer; did you mean to use '.'}}
+}
+
+typedef Derived *Foo;
+
+void test2(Foo d) {
+  d.~Foo(); // This is ok
+  d.~Derived(); // expected-error {{member reference type 'Foo' (aka 'dotPointerAccess::Derived *') is a pointer; did you mean to use '->'}}
+}
+}
Index: test/CXX/special/class.dtor/p10-0x.cpp
===================================================================
--- test/CXX/special/class.dtor/p10-0x.cpp
+++ test/CXX/special/class.dtor/p10-0x.cpp
@@ -33,7 +33,7 @@
                              expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   pi->~decltype(int())();
-  pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+  pi.~decltype(int())(); // expected-error{{member reference type 'int *' is a pointer; did you mean to use '->'?}}
   pi.~decltype(intp())();
   pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
 }
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -6279,9 +6279,20 @@
       = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin();
     if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) {
       if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
-        Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
-          << ObjectType << DestructedType << Base->getSourceRange()
-          << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+        // Detect dot pseudo destructor calls on pointer objects, e.g.:
+        //   Foo *foo;
+        //   foo.~Foo();
+        if (OpKind == tok::period && ObjectType->isPointerType() &&
+            Context.hasSameUnqualifiedType(DestructedType,
+                                           ObjectType->getPointeeType())) {
+          Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+              << ObjectType << /*IsArrow=*/0 << Base->getSourceRange()
+              << FixItHint::CreateReplacement(OpLoc, "->");
+        } else {
+          Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
+              << ObjectType << DestructedType << Base->getSourceRange()
+              << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+        }
 
         // Recover by setting the destructed type to the object type.
         DestructedType = ObjectType;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25817.75275.patch
Type: text/x-patch
Size: 3597 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161020/55271943/attachment-0001.bin>


More information about the cfe-commits mailing list