Author: dcoughlin Date: Mon Mar 28 18:55:58 2016 New Revision: 264687 URL: http://llvm.org/viewvc/llvm-project?rev=264687&view=rev Log: [analyzer] Use BodyFarm-synthesized body even when actual body available.
Change body autosynthesis to use the BodyFarm-synthesized body even when an actual body exists. This enables the analyzer to use the simpler, analyzer-provided body to model the behavior of the function rather than trying to understand the actual body. Further, this makes the analyzer robust against changes in headers that expose the implementations of those bodies. rdar://problem/25145950 Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp cfe/trunk/test/Analysis/NSString.m cfe/trunk/test/Analysis/properties.m Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp?rev=264687&r1=264686&r2=264687&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp (original) +++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Mon Mar 28 18:55:58 2016 @@ -94,19 +94,25 @@ Stmt *AnalysisDeclContext::getBody(bool IsAutosynthesized = false; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { Stmt *Body = FD->getBody(); - if (!Body && Manager && Manager->synthesizeBodies()) { - Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD); - if (Body) + if (Manager && Manager->synthesizeBodies()) { + Stmt *SynthesizedBody = + getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD); + if (SynthesizedBody) { + Body = SynthesizedBody; IsAutosynthesized = true; + } } return Body; } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { Stmt *Body = MD->getBody(); - if (!Body && Manager && Manager->synthesizeBodies()) { - Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD); - if (Body) + if (Manager && Manager->synthesizeBodies()) { + Stmt *SynthesizedBody = + getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD); + if (SynthesizedBody) { + Body = SynthesizedBody; IsAutosynthesized = true; + } } return Body; } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) Modified: cfe/trunk/test/Analysis/NSString.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString.m?rev=264687&r1=264686&r2=264687&view=diff ============================================================================== --- cfe/trunk/test/Analysis/NSString.m (original) +++ cfe/trunk/test/Analysis/NSString.m Mon Mar 28 18:55:58 2016 @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-objc-root-class %s // RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-constraints=range -analyzer-config mode=shallow -verify -Wno-objc-root-class %s // RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-objc-root-class %s - +// RUN: %clang_cc1 -DOSATOMIC_USE_INLINED -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-objc-root-class %s //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from @@ -279,9 +279,22 @@ id testSharedClassFromFunction() { return [[SharedClass alloc] _init]; // no-warning } +#if !(defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED) // Test OSCompareAndSwap _Bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ); extern BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation); +#else +// Test that the body farm models are still used even when a body is available. +_Bool opaque_OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ); +_Bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) { + return opaque_OSAtomicCompareAndSwapPtr(__oldValue, __newValue, __theValue); +} + +extern BOOL opaque_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); +} +#endif void testOSCompareAndSwap() { NSString *old = 0; Modified: cfe/trunk/test/Analysis/properties.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/properties.m?rev=264687&r1=264686&r2=264687&view=diff ============================================================================== --- cfe/trunk/test/Analysis/properties.m (original) +++ cfe/trunk/test/Analysis/properties.m Mon Mar 28 18:55:58 2016 @@ -247,6 +247,25 @@ void testConsistencyAssign(Person *p) { } @end +@interface ClassWithSynthesizedPropertyAndGetter +@property (readonly) int someProp; +@end + +@implementation ClassWithSynthesizedPropertyAndGetter +@synthesize someProp; + +// Make sure that the actual getter is inlined and not a getter created +// by BodyFarm +- (void)testBodyFarmGetterNotUsed { + int i = self.someProp; + clang_analyzer_eval(i == 22); // expected-warning {{TRUE}} +} + +-(int)someProp { + return 22; +} +@end + //------ // Setter ivar invalidation. //------ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits