summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaLambda.cpp13
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp4
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp4
-rw-r--r--clang/test/CodeGenCXX/debug-info-lambda.cpp16
-rw-r--r--clang/test/SemaCXX/uninitialized.cpp6
-rw-r--r--clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp10
6 files changed, 36 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 33915676585..8000cb4fbfd 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1392,13 +1392,14 @@ static void addBlockPointerConversion(Sema &S,
Class->addDecl(Conversion);
}
-static ExprResult performLambdaVarCaptureInitialization(Sema &S,
- const Capture &Capture,
- FieldDecl *Field) {
+static ExprResult performLambdaVarCaptureInitialization(
+ Sema &S, const Capture &Capture, FieldDecl *Field,
+ SourceLocation ImplicitCaptureLoc, bool IsImplicitCapture) {
assert(Capture.isVariableCapture() && "not a variable capture");
auto *Var = Capture.getVariable();
- SourceLocation Loc = Capture.getLocation();
+ SourceLocation Loc =
+ IsImplicitCapture ? ImplicitCaptureLoc : Capture.getLocation();
// C++11 [expr.prim.lambda]p21:
// When the lambda-expression is evaluated, the entities that
@@ -1607,8 +1608,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
Var, From.getEllipsisLoc()));
Expr *Init = From.getInitExpr();
if (!Init) {
- auto InitResult =
- performLambdaVarCaptureInitialization(*this, From, *CurField);
+ auto InitResult = performLambdaVarCaptureInitialization(
+ *this, From, *CurField, CaptureDefaultLoc, IsImplicit);
if (InitResult.isInvalid())
return ExprError();
Init = InitResult.get();
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
index 551c100ff7a..7fc86e81092 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
@@ -15,8 +15,8 @@ public:
void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) {
(void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}}
- (void)[=] {
- ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
+ (void)[=] { // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
+ ncr.foo();
}();
[nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}}
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
index 57e555e8d9e..2bb75df7ac6 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
@@ -88,8 +88,8 @@ namespace p2 {
template<typename R, typename T>
void odr_used2(R &r, Boom<T> boom) {
const std::type_info &ti
- = typeid([=,&r] () -> R& {
- boom.tickle(); // expected-note{{in instantiation of member function}}
+ = typeid([=,&r] () -> R& { // expected-note{{in instantiation of member function 'p2::Boom<float>::Boom' requested here}}
+ boom.tickle();
return r;
}());
}
diff --git a/clang/test/CodeGenCXX/debug-info-lambda.cpp b/clang/test/CodeGenCXX/debug-info-lambda.cpp
new file mode 100644
index 00000000000..1b8f4e3cd32
--- /dev/null
+++ b/clang/test/CodeGenCXX/debug-info-lambda.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm \
+// RUN: -debug-info-kind=line-tables-only -dwarf-column-info -std=c++11 %s -o - | FileCheck %s
+
+// CHECK-LABEL: define{{.*}}lambda_in_func
+void lambda_in_func(int &ref) {
+ // CHECK: [[ref_slot:%.*]] = getelementptr inbounds %class.anon, %class.anon* {{.*}}, i32 0, i32 0, !dbg [[lambda_decl_loc:![0-9]+]]
+ // CHECK-NEXT: %1 = load i32*, i32** %ref.addr, align 8, !dbg [[capture_init_loc:![0-9]+]]
+ // CHECK-NEXT: store i32* %1, i32** %0, align 8, !dbg [[lambda_decl_loc]]
+ // CHECK-NEXT: call void {{.*}}, !dbg [[lambda_call_loc:![0-9]+]]
+
+ auto helper = [ // CHECK: [[lambda_decl_loc]] = !DILocation(line: [[@LINE]], column: 17
+ &]() { // CHECK: [[capture_init_loc]] = !DILocation(line: [[@LINE]], column: 18
+ ++ref;
+ };
+ helper(); // CHECK: [[lambda_call_loc]] = !DILocation(line: [[@LINE]]
+}
diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp
index f620e1014c3..331a948eb6f 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -884,8 +884,10 @@ namespace lambdas {
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}}
+ void f() {
+ A a1([=] { // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
+ return a1.x;
+ });
A a2([&] { return a2.x; }); // ok
}
}
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
index 67640486efb..cd0e4260a8b 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
@@ -75,11 +75,11 @@ TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) {
TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) {
DeclRefExprVisitor Visitor;
Visitor.setShouldVisitImplicitCode(true);
- // We're expecting the "i" in the lambda to be visited twice:
- // - Once for the DeclRefExpr in the lambda capture initialization (whose
- // source code location is set to the first use of the variable).
- // - Once for the DeclRefExpr for the use of "i" inside the lambda.
- Visitor.ExpectMatch("i", 1, 24, /*Times=*/2);
+ // We're expecting "i" to be visited twice: once for the initialization expr
+ // for the captured variable "i" outside of the lambda body, and again for
+ // the use of "i" inside the lambda.
+ Visitor.ExpectMatch("i", 1, 20, /*Times=*/1);
+ Visitor.ExpectMatch("i", 1, 24, /*Times=*/1);
EXPECT_TRUE(Visitor.runOver(
"void f() { int i; [=]{ i; }; }",
DeclRefExprVisitor::Lang_CXX11));
OpenPOWER on IntegriCloud