aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-09-14 22:55:20 +0000
committerDouglas Gregor <dgregor@apple.com>2010-09-14 22:55:20 +0000
commit5833b0b831d6afae2885e6af420e2bda639652e6 (patch)
tree9cd679ee2d9b42308f7c88f81f1b1665564a414d /lib
parent4178b573b82449c2d888ea1f0957a478534e118c (diff)
When marking the declarations in a default argument expression as
"used", at the time that the default argument itself is used, also mark destructors that will be called by this expression. This fixes a regression that I introduced in r113700, which broke WebKit, and fixes <rdar://problem/8427926>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113883 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ExprCXX.cpp13
-rw-r--r--lib/Sema/SemaExpr.cpp15
-rw-r--r--lib/Sema/TreeTransform.h11
3 files changed, 37 insertions, 2 deletions
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index a6aeef1ba8..6e73b9cbc2 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -149,6 +149,19 @@ Stmt::child_iterator CXXNewExpr::child_end() {
}
// CXXDeleteExpr
+QualType CXXDeleteExpr::getDestroyedType() const {
+ const Expr *Arg = getArgument();
+ while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
+ if (ICE->getCastKind() != CK_UserDefinedConversion &&
+ ICE->getType()->isVoidPointerType())
+ Arg = ICE->getSubExpr();
+ else
+ break;
+ }
+
+ return Arg->getType()->getAs<PointerType>()->getPointeeType();
+}
+
Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9a394aeeb9..533d04f7ec 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3454,8 +3454,12 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
// be properly destroyed.
// FIXME: We should really be rebuilding the default argument with new
// bound temporaries; see the comment in PR5810.
- for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i)
- ExprTemporaries.push_back(Param->getDefaultArgTemporary(i));
+ for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i) {
+ CXXTemporary *Temporary = Param->getDefaultArgTemporary(i);
+ MarkDeclarationReferenced(Param->getDefaultArg()->getLocStart(),
+ const_cast<CXXDestructorDecl*>(Temporary->getDestructor()));
+ ExprTemporaries.push_back(Temporary);
+ }
// We already type-checked the argument, so we know it works.
// Just mark all of the declarations in this potentially-evaluated expression
@@ -7838,6 +7842,13 @@ namespace {
void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
if (E->getOperatorDelete())
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete());
+ QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType());
+ if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
+ CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
+ S.MarkDeclarationReferenced(E->getLocStart(),
+ S.LookupDestructor(Record));
+ }
+
Inherited::VisitCXXDeleteExpr(E);
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 765ce0f5e8..a865348e49 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -5395,6 +5395,17 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
// FIXME: instantiation-specific.
if (OperatorDelete)
SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
+
+ if (!E->getArgument()->isTypeDependent()) {
+ QualType Destroyed = SemaRef.Context.getBaseElementType(
+ E->getDestroyedType());
+ if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
+ CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
+ SemaRef.MarkDeclarationReferenced(E->getLocStart(),
+ SemaRef.LookupDestructor(Record));
+ }
+ }
+
return SemaRef.Owned(E->Retain());
}