[analyzer] Don't attempt to devirtualize calls to base class destructors.

CXXDestructorCall now has a flag for when it is a base destructor call.
Other kinds of destructor calls (locals, fields, temporaries, and 'delete')
all behave as "whole-object" destructors and do not behave differently
from one another (specifically, in these cases we /should/ try to
devirtualize a call to a virtual destructor).

This was causing crashes in both our internal buildbot, the crash still
being tracked in PR13765, and some of the crashes being tracked in PR13763,
due to a assertion failure. (The behavior under -Asserts happened to be
correct anyway.)

Adding this knowledge also allows our DynamicTypePropagation checker to do
a bit less work; the special rules about virtual method calls during a
destructor only require extra handling during base destructors.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163348 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index a762ebe..99c47d5 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -251,3 +251,33 @@
     free(p); // no-warning
   }
 }
+
+namespace MultipleInheritanceVirtualDtors {
+  class VirtualDtor {
+  protected:
+    virtual ~VirtualDtor() {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+    }
+  };
+
+  class NonVirtualDtor {
+  protected:
+    ~NonVirtualDtor() {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+    }
+  };
+
+  class SubclassA : public VirtualDtor, public NonVirtualDtor {
+  public:
+    virtual ~SubclassA() {}
+  };
+  class SubclassB : public NonVirtualDtor, public VirtualDtor {
+  public:
+    virtual ~SubclassB() {}
+  };
+
+  void test() {
+    SubclassA a;
+    SubclassB b;
+  }
+}