]> granicus.if.org Git - clang/commitdiff
PR15906: The body of a lambda is not an evaluated subexpression; don't visit it when...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 3 May 2013 19:16:22 +0000 (19:16 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 3 May 2013 19:16:22 +0000 (19:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181046 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/EvaluatedExprVisitor.h
lib/Sema/SemaDecl.cpp
test/SemaCXX/uninitialized.cpp

index eb186c217e357648b34384a82b097e8b7e234eb1..2e3cbfad919dea0ebea26f503018aeb0202fe509 100644 (file)
@@ -55,7 +55,7 @@ public:
     // 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 @@ public:
       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) {
index 5e0d7f2a0ae6de3916c1cf3112bae16c6443dbc5..f5b4823fdb72399304e7be127c7e35c304d18e9f 100644 (file)
@@ -7212,7 +7212,7 @@ namespace {
         return;
       }
       Inherited::VisitUnaryOperator(E);
-    } 
+    }
 
     void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; }
 
index 2aa56623f6993177639c513fc9cda121f3a8f33e..665cfe7e91182e7b6b25097ec94765ed9e5cd3c2 100644 (file)
@@ -511,3 +511,15 @@ namespace operators {
 
   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
+  }
+}