summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorDevin Coughlin <dcoughlin@apple.com>2015-11-15 03:07:17 +0000
committerDevin Coughlin <dcoughlin@apple.com>2015-11-15 03:07:17 +0000
commite69b043088388837a744a2463902b39b320a4d2f (patch)
treebeaea6c18b8df3bd367c3c2a94b7362e2d494657 /clang/test
parent7f77eb90a54c96168d6cce8ad3a85d1454cdb80c (diff)
downloadbcm5719-llvm-e69b043088388837a744a2463902b39b320a4d2f.tar.gz
bcm5719-llvm-e69b043088388837a744a2463902b39b320a4d2f.zip
[analyzer] Refer to capture field to determine if capture is reference.
The analyzer incorrectly treats captures as references if either the original captured variable is a reference or the variable is captured by reference. This causes the analyzer to crash when capturing a reference type by copy (PR24914). Fix this by refering solely to the capture field to determine when a DeclRefExpr for a lambda capture should be treated as a reference type. https://llvm.org/bugs/show_bug.cgi?id=24914 rdar://problem/23524412 llvm-svn: 253157
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Analysis/lambdas.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/clang/test/Analysis/lambdas.cpp b/clang/test/Analysis/lambdas.cpp
index 10f6d559582..a906cedb3a9 100644
--- a/clang/test/Analysis/lambdas.cpp
+++ b/clang/test/Analysis/lambdas.cpp
@@ -90,6 +90,17 @@ void testReturnValue() {
clang_analyzer_eval(b == 8); // expected-warning{{TRUE}}
}
+void testAliasingBetweenParameterAndCapture() {
+ int i = 5;
+
+ auto l = [&i](int &p) {
+ i++;
+ p++;
+ };
+ l(i);
+ clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
+}
+
// Nested lambdas.
void testNestedLambdas() {
@@ -210,6 +221,67 @@ void captureConstants() {
}();
}
+void captureReferenceByCopy(int &p) {
+ int v = 7;
+ p = 8;
+
+ // p is a reference captured by copy
+ [&v,p]() mutable {
+ v = p;
+ p = 22;
+ }();
+
+ clang_analyzer_eval(v == 8); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p == 8); // expected-warning{{TRUE}}
+}
+
+void captureReferenceByReference(int &p) {
+ int v = 7;
+ p = 8;
+
+ // p is a reference captured by reference
+ [&v,&p]() {
+ v = p;
+ p = 22;
+ }();
+
+ clang_analyzer_eval(v == 8); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p == 22); // expected-warning{{TRUE}}
+}
+
+void callMutableLambdaMultipleTimes(int &p) {
+ int v = 0;
+ p = 8;
+
+ auto l = [&v, p]() mutable {
+ v = p;
+ p++;
+ };
+
+ l();
+
+ clang_analyzer_eval(v == 8); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p == 8); // expected-warning{{TRUE}}
+
+ l();
+
+ clang_analyzer_eval(v == 9); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p == 8); // expected-warning{{TRUE}}
+}
+
+// PR 24914
+struct StructPR24914{
+ int x;
+};
+
+void takesConstStructArgument(const StructPR24914&);
+void captureStructReference(const StructPR24914& s) {
+ [s]() {
+ takesConstStructArgument(s);
+ }();
+}
+
+
// CHECK: [B2 (ENTRY)]
// CHECK: Succs (1): B1
// CHECK: [B1]
OpenPOWER on IntegriCloud