From: Douglas Gregor Date: Tue, 14 Sep 2010 22:55:20 +0000 (+0000) Subject: When marking the declarations in a default argument expression as X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5833b0b831d6afae2885e6af420e2bda639652e6;p=clang 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 . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113883 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 1424d8899b..6a3d307b08 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1136,6 +1136,8 @@ public: Expr *getArgument() { return cast(Argument); } const Expr *getArgument() const { return cast(Argument); } + QualType getDestroyedType() const; + virtual SourceRange getSourceRange() const { return SourceRange(Loc, Argument->getLocEnd()); } 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(Arg)) { + if (ICE->getCastKind() != CK_UserDefinedConversion && + ICE->getType()->isVoidPointerType()) + Arg = ICE->getSubExpr(); + else + break; + } + + return Arg->getType()->getAs()->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(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()) { + CXXRecordDecl *Record = cast(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::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()) { + CXXRecordDecl *Record = cast(DestroyedRec->getDecl()); + SemaRef.MarkDeclarationReferenced(E->getLocStart(), + SemaRef.LookupDestructor(Record)); + } + } + return SemaRef.Owned(E->Retain()); } diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index 8fc241d5b2..eff59a84e3 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -252,3 +252,25 @@ namespace PR8127 { void foo( PointerClass = 0 ); }; } + +namespace rdar8427926 { + template + struct Boom { + ~Boom() { + T t; + double *******ptr = t; // expected-error 2{{cannot initialize}} + } + }; + + Boom *bfp; + + struct X { + void f(Boom = Boom()) { } // expected-note{{requested here}} + void g(int x = (delete bfp, 0)); // expected-note{{requested here}} + }; + + void test(X *x) { + x->f(); + x->g(); + } +}