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