diff options
| author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-04-25 23:02:06 +0000 |
|---|---|---|
| committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-04-25 23:02:06 +0000 |
| commit | 310bca01781bff0d71c2d69a952b3a7bd6b6ef2a (patch) | |
| tree | 3837d95a2816d6648794c0ff5199ed4e5176ae92 /clang/test | |
| parent | 0bf96f933a0cae717d8311785db8485aeacabf1b (diff) | |
| download | bcm5719-llvm-310bca01781bff0d71c2d69a952b3a7bd6b6ef2a.tar.gz bcm5719-llvm-310bca01781bff0d71c2d69a952b3a7bd6b6ef2a.zip | |
[analyzer] Fix a crash on lifetime extension through aggregate initialization.
If 'A' is a C++ aggregate with a reference field of type 'C', in code like
A a = { C() };
C() is lifetime-extended by 'a'. The analyzer wasn't expecting this pattern and
crashing. Additionally, destructors aren't added in the CFG for this case,
so for now we shouldn't be inlining the constructor for C().
Differential Revision: https://reviews.llvm.org/D46037
llvm-svn: 330882
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Analysis/lifetime-extension.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/clang/test/Analysis/lifetime-extension.cpp b/clang/test/Analysis/lifetime-extension.cpp index c9038a2b5bb..9173129ac14 100644 --- a/clang/test/Analysis/lifetime-extension.cpp +++ b/clang/test/Analysis/lifetime-extension.cpp @@ -147,6 +147,37 @@ void f5() { // FIXME: Should be TRUE. Should not warn about garbage value. clang_analyzer_eval(after == before); // expected-warning{{UNKNOWN}} } + +struct A { // A is an aggregate. + const C &c; +}; + +void f6() { + C *after, *before; + { + A a{C(true, &after, &before)}; + } + // FIXME: Should be TRUE. Should not warn about garbage value. + clang_analyzer_eval(after == before); // expected-warning{{UNKNOWN}} +} + +void f7() { + C *after, *before; + { + A a = {C(true, &after, &before)}; + } + // FIXME: Should be TRUE. Should not warn about garbage value. + clang_analyzer_eval(after == before); // expected-warning{{UNKNOWN}} +} + +void f8() { + C *after, *before; + { + A a[2] = {C(false, nullptr, nullptr), C(true, &after, &before)}; + } + // FIXME: Should be TRUE. Should not warn about garbage value. + clang_analyzer_eval(after == before); // expected-warning{{UNKNOWN}} +} } // end namespace maintain_original_object_address_on_lifetime_extension namespace maintain_original_object_address_on_move { |

