[analyzer] Fix a crash in RetainCountChecker - we should not rely on CallEnter::getCallExpr to return non-NULL

We get a CallEnter with a null expression, when processing a destructor. All other users of
CallEnter::getCallExpr work fine with null as return value.

(Addresses PR15832, Thanks to Jordan for reducing the test case!)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180234 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 824ce34..0d25600 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2192,7 +2192,7 @@
     if (!InitMethodContext)
       if (Optional<CallEnter> CEP = N->getLocation().getAs<CallEnter>()) {
         const Stmt *CE = CEP->getCallExpr();
-        if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(CE)) {
+        if (const ObjCMessageExpr *ME = dyn_cast_or_null<ObjCMessageExpr>(CE)) {
           const Stmt *RecExpr = ME->getInstanceReceiver();
           if (RecExpr) {
             SVal RecV = St->getSVal(RecExpr, NContext);
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index 47d67ea..3650d88 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -83,6 +83,7 @@
 enum {
 kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
 extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+extern CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef theString);
 typedef double CFTimeInterval;
 typedef CFTimeInterval CFAbsoluteTime;
 extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
@@ -269,7 +270,6 @@
     CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
     CGGradientDrawingOptions options);
 extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
-
 //===----------------------------------------------------------------------===//
 // Test cases.
 //===----------------------------------------------------------------------===//
@@ -408,3 +408,56 @@
 }
 @end
 
+//===----------------------------------------------------------------------===//
+// Don't crash on getting a null expression from CallEnter corresponding to a
+// destructor.
+//===----------------------------------------------------------------------===//
+
+template <typename X>
+class Holder {
+public:
+	Holder() throw();
+	~Holder() throw() {}
+	X* get() const throw();
+	void reset(X* p) throw();
+private:
+	X* ptr_;
+};
+
+template<typename X>
+inline
+Holder<X>::Holder() throw()
+: ptr_(0){}
+
+template <typename X>
+inline
+X* Holder<X>::get() const throw() {
+	return ptr_;
+}
+
+template <typename X>
+inline
+void Holder<X>::reset(X* p) throw() {
+	if (ptr_ != p) {
+		if (ptr_ != 0) {
+			::CFRelease( ptr_ );
+		}
+		ptr_ = p;
+	}
+}
+
+class radar13722286 {
+public:
+  radar13722286() {}
+private:
+	void			PrepareBitmap();
+	Holder<const struct __CFString>	mStr;
+};
+
+void	radar13722286::PrepareBitmap() {
+	if (mStr.get() != 0) {
+		Holder<const struct __CFString> str1;
+		mStr.reset( CFStringCreateCopy( 0, str1.get() ) ); //expected-warning {{Potential leak of an object}}
+	}
+}
+