From: Douglas Gregor Date: Sat, 11 Sep 2010 23:32:50 +0000 (+0000) Subject: Teach the EvaluatedExprVisitor and its client, which marks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4fcf5b2f816347ba7a3f16557d5e2b293634d4d6;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113708 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h index 6835a76699..be606e0fda 100644 --- a/include/clang/AST/EvaluatedExprVisitor.h +++ b/include/clang/AST/EvaluatedExprVisitor.h @@ -67,6 +67,14 @@ public: if (cast(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); + } }; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b951b98cce..1152da9bdc 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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) { diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index c898e102bc..8fc241d5b2 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -218,6 +218,24 @@ namespace PR5810b { void g() { f(17); } } +namespace PR5810c { + template + 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 { // expected-note{{instantiation of}} + }; + + void f(Y y = Y()); + + void g() { f(); } +} + namespace PR8127 { template< typename T > class PointerClass { public: