diff options
| author | Henry Wong <movietravelcode@outlook.com> | 2018-04-15 10:34:06 +0000 |
|---|---|---|
| committer | Henry Wong <movietravelcode@outlook.com> | 2018-04-15 10:34:06 +0000 |
| commit | 525d4122c9ed09f50dee8683a14f4700cf5eb130 (patch) | |
| tree | d95a7c812eef453c2978a3612a947ca9d1d4d3c1 /clang/test/Analysis/this-pointer.cpp | |
| parent | 6be1f01935f23d92c967024ee718a7f48748283c (diff) | |
| download | bcm5719-llvm-525d4122c9ed09f50dee8683a14f4700cf5eb130.tar.gz bcm5719-llvm-525d4122c9ed09f50dee8683a14f4700cf5eb130.zip | |
[analyzer] Do not invalidate the `this` pointer.
Summary:
`this` pointer is not an l-value, although we have modeled `CXXThisRegion` for `this` pointer, we can only bind it once, which is when we start to inline method. And this patch fixes https://bugs.llvm.org/show_bug.cgi?id=35506.
In addition, I didn't find any other cases other than loop-widen that could invalidate `this` pointer.
Reviewers: NoQ, george.karpenkov, a.sidorin, seaneveson, szepet
Reviewed By: NoQ
Subscribers: xazax.hun, rnkovacs, cfe-commits, MTC
Differential Revision: https://reviews.llvm.org/D45491
llvm-svn: 330095
Diffstat (limited to 'clang/test/Analysis/this-pointer.cpp')
| -rw-r--r-- | clang/test/Analysis/this-pointer.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/clang/test/Analysis/this-pointer.cpp b/clang/test/Analysis/this-pointer.cpp new file mode 100644 index 00000000000..d160a942ef2 --- /dev/null +++ b/clang/test/Analysis/this-pointer.cpp @@ -0,0 +1,88 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config widen-loops=true -analyzer-disable-retry-exhausted -verify %s + +void clang_analyzer_eval(bool); +void clang_analyzer_dump(int); + +// 'this' pointer is not an lvalue, we should not invalidate it. +namespace this_pointer_after_loop_widen { +class A { +public: + A() { + int count = 10; + do { + } while (count--); + } +}; + +void goo(A a); +void test_temporary_object() { + goo(A()); // no-crash +} + +struct B { + int mem; + B() : mem(0) { + for (int i = 0; i < 10; ++i) { + } + mem = 0; + } +}; + +void test_ctor() { + B b; + clang_analyzer_eval(b.mem == 0); // expected-warning{{TRUE}} +} + +struct C { + int mem; + C() : mem(0) {} + void set() { + for (int i = 0; i < 10; ++i) { + } + mem = 10; + } +}; + +void test_method() { + C c; + clang_analyzer_eval(c.mem == 0); // expected-warning{{TRUE}} + c.set(); + clang_analyzer_eval(c.mem == 10); // expected-warning{{TRUE}} +} + +struct D { + int mem; + D() : mem(0) {} + void set() { + for (int i = 0; i < 10; ++i) { + } + mem = 10; + } +}; + +void test_new() { + D *d = new D; + clang_analyzer_eval(d->mem == 0); // expected-warning{{TRUE}} + d->set(); + clang_analyzer_eval(d->mem == 10); // expected-warning{{TRUE}} +} + +struct E { + int mem; + E() : mem(0) {} + void set() { + for (int i = 0; i < 10; ++i) { + } + setAux(); + } + void setAux() { + this->mem = 10; + } +}; + +void test_chained_method_call() { + E e; + e.set(); + clang_analyzer_eval(e.mem == 10); // expected-warning{{TRUE}} +} +} // namespace this_pointer_after_loop_widen |

