r180234 - [analyzer] Fix a crash in RetainCountChecker - we should not rely on CallEnter::getCallExpr to return non-NULL
Jordan Rose
jordan_rose at apple.com
Wed Apr 24 17:47:55 PDT 2013
Not my reduction; the originator's (James W. Walker). Glad it helped, though.
On Apr 24, 2013, at 17:41 , Anna Zaks <ganna at apple.com> wrote:
> Author: zaks
> Date: Wed Apr 24 19:41:32 2013
> New Revision: 180234
>
> URL: http://llvm.org/viewvc/llvm-project?rev=180234&view=rev
> Log:
> [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!)
>
> Modified:
> cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> cfe/trunk/test/Analysis/retain-release.mm
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=180234&r1=180233&r2=180234&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Wed Apr 24 19:41:32 2013
> @@ -2192,7 +2192,7 @@ GetAllocationSite(ProgramStateManager& S
> 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);
>
> Modified: cfe/trunk/test/Analysis/retain-release.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.mm?rev=180234&r1=180233&r2=180234&view=diff
> ==============================================================================
> --- cfe/trunk/test/Analysis/retain-release.mm (original)
> +++ cfe/trunk/test/Analysis/retain-release.mm Wed Apr 24 19:41:32 2013
> @@ -83,6 +83,7 @@ typedef UInt32 CFStringEncoding;
> 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 @@ extern void CGContextDrawLinearGradient(
> CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
> CGGradientDrawingOptions options);
> extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
> -
> //===----------------------------------------------------------------------===//
> // Test cases.
> //===----------------------------------------------------------------------===//
> @@ -408,3 +408,56 @@ void testCallback() {
> }
> @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}}
> + }
> +}
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list