Teach the EvaluatedExprVisitor and its client, which marks

declarations in potentially-evaluated subexpressions, about
recursion. Fixes the release-mode self-host failure I introduced in
r113700.

llvm-svn: 113708
This commit is contained in:
Douglas Gregor 2010-09-11 23:32:50 +00:00
parent cb67a14b3e
commit 32b3de519d
3 changed files with 32 additions and 0 deletions

View File

@ -67,6 +67,14 @@ public:
if (cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic())
return this->Visit(E->getExprOperand());
}
/// \brief The basis case walks all of the children of the statement or
/// expression, assuming they are all potentially evaluated.
void VisitStmt(Stmt *S) {
for(Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
C != CEnd; ++C)
this->Visit(*C);
}
};
}

View File

@ -3454,6 +3454,8 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
ExprTemporaries.push_back(Param->getDefaultArgTemporary(i));
// We already type-checked the argument, so we know it works.
// Just mark all of the declarations in this potentially-evaluated expression
// as being "referenced".
MarkDeclarationsReferencedInExpr(Param->getDefaultArg());
return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
}
@ -7816,6 +7818,7 @@ namespace {
void VisitMemberExpr(MemberExpr *E) {
S.MarkDeclarationReferenced(E->getMemberLoc(), E->getMemberDecl());
Inherited::VisitMemberExpr(E);
}
void VisitCXXNewExpr(CXXNewExpr *E) {
@ -7825,15 +7828,18 @@ namespace {
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorNew());
if (E->getOperatorDelete())
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete());
Inherited::VisitCXXNewExpr(E);
}
void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
if (E->getOperatorDelete())
S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete());
Inherited::VisitCXXDeleteExpr(E);
}
void VisitCXXConstructExpr(CXXConstructExpr *E) {
S.MarkDeclarationReferenced(E->getLocStart(), E->getConstructor());
Inherited::VisitCXXConstructExpr(E);
}
void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {

View File

@ -218,6 +218,24 @@ namespace PR5810b {
void g() { f(17); }
}
namespace PR5810c {
template<typename T>
struct X {
X() {
T t;
double *****p = t; // expected-error{{cannot initialize a variable of type 'double *****' with an lvalue of type 'int'}}
}
X(const X&) { }
};
struct Y : X<int> { // expected-note{{instantiation of}}
};
void f(Y y = Y());
void g() { f(); }
}
namespace PR8127 {
template< typename T > class PointerClass {
public: