]> granicus.if.org Git - clang/commitdiff
Teach the EvaluatedExprVisitor and its client, which marks
authorDouglas Gregor <dgregor@apple.com>
Sat, 11 Sep 2010 23:32:50 +0000 (23:32 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 11 Sep 2010 23:32:50 +0000 (23:32 +0000)
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

include/clang/AST/EvaluatedExprVisitor.h
lib/Sema/SemaExpr.cpp
test/SemaTemplate/default-expr-arguments.cpp

index 6835a76699a0961c0c37931e4e45b2a1eb07a83f..be606e0fda093bad9e88eb77495df14584f6243b 100644 (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);
+  }
 };
 
 }
index b951b98cce949511fcc42cb2db1eb507e04f2f63..1152da9bdc037647b4e3c4c524d3fe18251922e4 100644 (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) {
index c898e102bc19b5dbc246509b03b0054b9ccdd0ed..8fc241d5b2c5b3cb0b979db2bbb284fae935d36c 100644 (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: