diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2012-08-13 23:46:01 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-13 23:46:01 +0000 |
| commit | 710f6b1259fb9f13cfa34b3d093d6130b0fb8b3a (patch) | |
| tree | 3b145e5bb19b42e6b7d634618bcc6d8e1361f3a9 /clang/test/Analysis | |
| parent | a40319b7f1640612dda14f1f4f46bed913299775 (diff) | |
| download | bcm5719-llvm-710f6b1259fb9f13cfa34b3d093d6130b0fb8b3a.tar.gz bcm5719-llvm-710f6b1259fb9f13cfa34b3d093d6130b0fb8b3a.zip | |
[analyzer] Be more careful when downcasting for devirtualization.
Virtual base regions are never layered, so simply stripping them off won't
necessarily get you to the correct casted class. Instead, what we want is
the same logic for evaluating dynamic_cast: strip off base regions if possible,
but add new base regions if necessary.
llvm-svn: 161808
Diffstat (limited to 'clang/test/Analysis')
| -rw-r--r-- | clang/test/Analysis/inline.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/clang/test/Analysis/inline.cpp b/clang/test/Analysis/inline.cpp index 9a867849e5c..4eaed9fed13 100644 --- a/clang/test/Analysis/inline.cpp +++ b/clang/test/Analysis/inline.cpp @@ -106,6 +106,63 @@ namespace PR13569 { // Don't crash when inlining and devirtualizing. x.interface(); } + + + class Grandchild : public Child {}; + + void testDevirtualizeToMiddle() { + Grandchild x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } } +namespace PR13569_virtual { + class Parent { + protected: + int m_parent; + virtual int impl() const = 0; + Parent() : m_parent(0) {} + + public: + int interface() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return impl(); + } + }; + + class Child : virtual public Parent { + protected: + virtual int impl() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return m_parent + m_child; + } + + public: + Child() : m_child(0) {} + + int m_child; + }; + + void testVirtual() { + Child x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } + + + class Grandchild : virtual public Child {}; + + void testDevirtualizeToMiddle() { + Grandchild x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } +} |

