Inlining the relevant part of FinalizeVarWithDestructor makes it look like 
this.

Hi rnk, rsmith,

http://llvm-reviews.chandlerc.com/D2409

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2409?vs=6103&id=6154#toc

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  test/SemaCXX/microsoft-dtor-lookup.cpp
  test/SemaObjCXX/microsoft-abi-byval.mm
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3128,7 +3128,8 @@
   // needs to be delayed for some constant variables when we build one of the
   // named expressions.
   void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse);
-  void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
+  void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
+                              bool CheckAccess = true);
   void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
   void MarkDeclRefReferenced(DeclRefExpr *E);
   void MarkMemberReferenced(MemberExpr *E);
@@ -3890,7 +3891,8 @@
   /// DefineImplicitDestructor - Checks for feasibility of
   /// defining this destructor as the default destructor.
   void DefineImplicitDestructor(SourceLocation CurrentLocation,
-                                CXXDestructorDecl *Destructor);
+                                CXXDestructorDecl *Destructor,
+                                bool CheckAccess = true);
 
   /// \brief Build an exception spec for destructors that don't have one.
   ///
@@ -4718,7 +4720,8 @@
   /// mark all the non-trivial destructors of its members and bases as
   /// referenced.
   void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
-                                              CXXRecordDecl *Record);
+                                              CXXRecordDecl *Record,
+                                              bool CheckAccess = true);
 
   /// \brief The list of classes whose vtables have been used within
   /// this translation unit, and the source locations at which the
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -6197,8 +6197,16 @@
     if (getLangOpts().CPlusPlus && Context.getTargetInfo()
                                        .getCXXABI()
                                        .areArgsDestroyedLeftToRightInCallee()) {
-      if (const RecordType *RT = Param->getType()->getAs<RecordType>())
-        FinalizeVarWithDestructor(Param, RT);
+      if (const RecordType *RT = Param->getType()->getAs<RecordType>()) {
+        CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+        if (!ClassDecl->isInvalidDecl() &&
+            !ClassDecl->hasIrrelevantDestructor() &&
+            !ClassDecl->isDependentContext()) {
+          CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);
+          MarkFunctionReferenced(Param->getLocation(), Destructor, false);
+          DiagnoseUseOfDecl(Destructor, Param->getLocation());
+        }
+      }
     }
   }
 
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -3953,9 +3953,9 @@
   DiagnoseUninitializedFields(*this, Constructor);
 }
 
-void
-Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
-                                             CXXRecordDecl *ClassDecl) {
+void Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
+                                                  CXXRecordDecl *ClassDecl,
+                                                  bool CheckAccess) {
   // Ignore dependent contexts. Also ignore unions, since their members never
   // have destructors implicitly called.
   if (ClassDecl->isDependentContext() || ClassDecl->isUnion())
@@ -4026,11 +4026,12 @@
     assert(Dtor && "No dtor found for BaseClassDecl!");
 
     // FIXME: caret should be on the start of the class name
-    CheckDestructorAccess(Base->getLocStart(), Dtor,
-                          PDiag(diag::err_access_dtor_base)
-                            << Base->getType()
-                            << Base->getSourceRange(),
-                          Context.getTypeDeclType(ClassDecl));
+    if (CheckAccess)
+      CheckDestructorAccess(Base->getLocStart(), Dtor,
+                            PDiag(diag::err_access_dtor_base)
+                              << Base->getType()
+                              << Base->getSourceRange(),
+                            Context.getTypeDeclType(ClassDecl));
     
     MarkFunctionReferenced(Location, Dtor);
     DiagnoseUseOfDecl(Dtor, Location);
@@ -8706,7 +8707,8 @@
 }
 
 void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
-                                    CXXDestructorDecl *Destructor) {
+                                    CXXDestructorDecl *Destructor,
+                                    bool CheckAccess) {
   assert((Destructor->isDefaulted() &&
           !Destructor->doesThisDeclarationHaveABody() &&
           !Destructor->isDeleted()) &&
@@ -8721,7 +8723,8 @@
 
   DiagnosticErrorTrap Trap(Diags);
   MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
-                                         Destructor->getParent());
+                                         Destructor->getParent(),
+                                         CheckAccess);
 
   if (CheckDestructor(Destructor) || Trap.hasErrorOccurred()) {
     Diag(CurrentLocation, diag::note_member_synthesized_at) 
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -11148,7 +11148,8 @@
 
 /// \brief Mark a function referenced, and check whether it is odr-used
 /// (C++ [basic.def.odr]p2, C99 6.9p3)
-void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
+void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
+                                  bool CheckAccess) {
   assert(Func && "No function?");
 
   Func->setReferenced();
@@ -11214,7 +11215,7 @@
                  dyn_cast<CXXDestructorDecl>(Func)) {
     Destructor = cast<CXXDestructorDecl>(Destructor->getFirstDecl());
     if (Destructor->isDefaulted() && !Destructor->isDeleted())
-      DefineImplicitDestructor(Loc, Destructor);
+      DefineImplicitDestructor(Loc, Destructor, CheckAccess);
     if (Destructor->isVirtual())
       MarkVTableUsed(Loc, Destructor->getParent());
   } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(Func)) {
Index: test/SemaCXX/microsoft-dtor-lookup.cpp
===================================================================
--- test/SemaCXX/microsoft-dtor-lookup.cpp
+++ test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -28,18 +28,14 @@
 
 namespace Test2 {
 
-// In the MSVC ABI, functions must destroy their aggregate arguments.  foo
-// requires a dtor for B, but we can't implicitly define it because ~A is
-// private.  bar should be able to call A's private dtor without error, even
-// though MSVC rejects bar.
-
+// In the MSVC ABI, functions must destroy their aggregate arguments.
 class A {
 private:
-  ~A(); // expected-note 2{{declared private here}}
+  ~A();
   int a;
 };
 
-struct B : public A { // expected-error {{base class 'Test2::A' has private destructor}}
+struct B : public A {
   int b;
 };
 
@@ -53,8 +49,8 @@
   C o;
 };
 
-void foo(B b) { } // expected-note {{implicit destructor for 'Test2::B' first required here}}
-void bar(A a) { } // expected-error {{variable of type 'Test2::A' has private destructor}}
+void foo(B b) { } // no error; MSVC rejects this, but the standard allows it.
+void bar(A a) { } // no error; MSVC rejects this, but the standard allows it.
 void baz(D d) { } // no error
 
 }
@@ -64,13 +60,13 @@
 
 class A {
   A();
-  ~A(); // expected-note 2{{implicitly declared private here}}
+  ~A(); // expected-note {{implicitly declared private here}}
   friend void bar(A);
   int a;
 };
 
 void bar(A a) { }
-void baz(A a) { } // expected-error {{variable of type 'Test3::A' has private destructor}}
+void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.
 
 // MSVC accepts foo() but we reject it for consistency with Itanium.  MSVC also
 // rejects this if A has a copy ctor or if we call A's ctor.
Index: test/SemaObjCXX/microsoft-abi-byval.mm
===================================================================
--- test/SemaObjCXX/microsoft-abi-byval.mm
+++ test/SemaObjCXX/microsoft-abi-byval.mm
@@ -1,14 +1,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -cxx-abi microsoft -Wno-objc-root-class %s
+// expected-no-diagnostics
 
 class Foo {
-  ~Foo(); // expected-note {{implicitly declared private here}}
+  ~Foo();
 };
 
 @interface bar
 - (void) my_method: (Foo)arg;
 @end
 
 @implementation bar
-- (void) my_method: (Foo)arg { // expected-error {{variable of type 'Foo' has private destructor}}
+- (void) my_method: (Foo)arg { // no error; MS ABI will call Foo's dtor, but we skip the access check.
 }
 @end
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to