PR15906: The body of a lambda is not an evaluated subexpression; don't visit it when visiting such subexpressions.

llvm-svn: 181046
diff --git a/clang/include/clang/AST/EvaluatedExprVisitor.h b/clang/include/clang/AST/EvaluatedExprVisitor.h
index eb186c2..2e3cbfa 100644
--- a/clang/include/clang/AST/EvaluatedExprVisitor.h
+++ b/clang/include/clang/AST/EvaluatedExprVisitor.h
@@ -55,7 +55,7 @@
     // Only the selected subexpression matters; the other one is not evaluated.
     return this->Visit(E->getChosenSubExpr(Context));
   }
-                 
+
   void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
     // Only the actual initializer matters; the designators are all constant
     // expressions.
@@ -72,6 +72,15 @@
       return static_cast<ImplClass*>(this)->VisitExpr(CE);
   }
 
+  void VisitLambdaExpr(LambdaExpr *LE) {
+    // Only visit the capture initializers, and not the body.
+    for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(),
+                                           E = LE->capture_init_end();
+         I != E; ++I)
+      if (*I)
+        this->Visit(*I);
+  }
+
   /// \brief The basis case walks all of the children of the statement or
   /// expression, assuming they are all potentially evaluated.
   void VisitStmt(Stmt *S) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5e0d7f2..f5b4823 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7212,7 +7212,7 @@
         return;
       }
       Inherited::VisitUnaryOperator(E);
-    } 
+    }
 
     void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; }
 
diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp
index 2aa5662..665cfe7 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -511,3 +511,15 @@
 
   int x = x = 5;
 }
+
+namespace lambdas {
+  struct A {
+    template<typename T> A(T) {}
+    int x;
+  };
+  A a0([] { return a0.x; }); // ok
+  void f() { 
+    A a1([=] { return a1.x; }); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
+    A a2([&] { return a2.x; }); // ok
+  }
+}