diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2015-11-15 03:07:17 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2015-11-15 03:07:17 +0000 |
commit | e69b043088388837a744a2463902b39b320a4d2f (patch) | |
tree | beaea6c18b8df3bd367c3c2a94b7362e2d494657 /clang/test | |
parent | 7f77eb90a54c96168d6cce8ad3a85d1454cdb80c (diff) | |
download | bcm5719-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.cpp | 72 |
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] |