[analyzer] Fix crash in RetainCountChecker::checkEndFunction

The class BodyFarm creates bodies for
OSAtomicCompareAndSwap*, objc_atomicCompareAndSwap*, dispatch_sync*, dispatch_once*
and for them the flag isBodyAutosynthesized is set to true.

This diff
1. makes AnalysisConsumer::HandleCode skip the autosynthesized code
2. replaces assert(LCtx->getParent()) in RetainCountChecker::checkEndFunction
by assert(!LCtx->inTopFrame()) (minor cleanup)

Test plan: make -j8 check-clang-analysis

Differential revision: https://reviews.llvm.org/D24792

llvm-svn: 282293
This commit is contained in:
Alexander Shaposhnikov 2016-09-23 20:49:01 +00:00
parent 2d1d944f7e
commit a1fead293f
3 changed files with 13 additions and 5 deletions

View File

@ -3863,7 +3863,7 @@ void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const {
// Don't process anything within synthesized bodies. // Don't process anything within synthesized bodies.
const LocationContext *LCtx = Pred->getLocationContext(); const LocationContext *LCtx = Pred->getLocationContext();
if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) { if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
assert(LCtx->getParent()); assert(!LCtx->inTopFrame());
return; return;
} }

View File

@ -652,6 +652,12 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
if (Mode == AM_None) if (Mode == AM_None)
return; return;
// Clear the AnalysisManager of old AnalysisDeclContexts.
Mgr->ClearContexts();
// Ignore autosynthesized code.
if (Mgr->getAnalysisDeclContext(D)->isBodyAutosynthesized())
return;
DisplayFunction(D, Mode, IMode); DisplayFunction(D, Mode, IMode);
CFG *DeclCFG = Mgr->getCFG(D); CFG *DeclCFG = Mgr->getCFG(D);
if (DeclCFG) { if (DeclCFG) {
@ -659,8 +665,6 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
MaxCFGSize = MaxCFGSize < CFGSize ? CFGSize : MaxCFGSize; MaxCFGSize = MaxCFGSize < CFGSize ? CFGSize : MaxCFGSize;
} }
// Clear the AnalysisManager of old AnalysisDeclContexts.
Mgr->ClearContexts();
BugReporter BR(*Mgr); BugReporter BR(*Mgr);
if (Mode & AM_Syntax) if (Mode & AM_Syntax)

View File

@ -289,7 +289,11 @@ _Bool opaque_OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void
_Bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) { _Bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) {
return opaque_OSAtomicCompareAndSwapPtr(__oldValue, __newValue, __theValue); return opaque_OSAtomicCompareAndSwapPtr(__oldValue, __newValue, __theValue);
} }
// Test that the analyzer doesn't crash when the farm model is used.
// The analyzer ignores the autosynthesized code.
_Bool OSAtomicCompareAndSwapEmptyFunction( void *__oldValue, void *__newValue, void * volatile *__theValue ) {
return 0;
}
extern BOOL opaque_objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation); extern BOOL opaque_objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation);
extern BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) { extern BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) {
return opaque_objc_atomicCompareAndSwapPtr(predicate, replacement, objectLocation); return opaque_objc_atomicCompareAndSwapPtr(predicate, replacement, objectLocation);
@ -441,4 +445,4 @@ void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) {
- (void)callValue { - (void)callValue {
[self _value]; [self _value];
} }
@end @end