Summary: public The static and global variables used in blocks don't appear in the ast as captured. We need them however to try and find retain cycles involving those variables. This diff adds a way of collecting the static variables used in blocks and treat them like we treat other captured variables to find retain cycles. Reviewed By: ddino Differential Revision: D2663727 fb-gh-sync-id: d5b44ecmaster
parent
930eaba2d5
commit
87a3d693e1
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
typedef void (^MyHandler) (NSString *name);
|
||||||
|
|
||||||
|
@interface C : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, strong) MyHandler handler;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSString *name;
|
||||||
|
@property (nonatomic,strong) C *bla1;
|
||||||
|
@property (nonatomic,strong) C *bla2;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation C
|
||||||
|
|
||||||
|
- (void) foo {
|
||||||
|
static dispatch_once_t once;
|
||||||
|
static C* sharedInstance1;
|
||||||
|
dispatch_once(&once, ^{
|
||||||
|
sharedInstance1 = [[C alloc] init];
|
||||||
|
});
|
||||||
|
static C* sharedInstance2;
|
||||||
|
dispatch_once(&once, ^{
|
||||||
|
sharedInstance2 = [[C alloc] init];
|
||||||
|
});
|
||||||
|
|
||||||
|
_bla1 = sharedInstance1;
|
||||||
|
_bla2 = sharedInstance2;
|
||||||
|
sharedInstance2.handler = ^(NSString* s){
|
||||||
|
_name = sharedInstance2.name;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
C *c = [[C alloc] init];
|
||||||
|
[c foo];
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package endtoend.objc;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static utils.matchers.ResultContainsErrorInMethod.contains;
|
||||||
|
import static utils.matchers.ResultContainsExactly.containsExactly;
|
||||||
|
import static utils.matchers.ResultContainsNoErrorInMethod.doesNotContain;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import utils.DebuggableTemporaryFolder;
|
||||||
|
import utils.InferException;
|
||||||
|
import utils.InferResults;
|
||||||
|
import utils.InferRunner;
|
||||||
|
|
||||||
|
public class RetainCycleStaticVarTest {
|
||||||
|
|
||||||
|
public static final String FILE =
|
||||||
|
"infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleStaticVar.m";
|
||||||
|
|
||||||
|
private static ImmutableList<String> inferCmd;
|
||||||
|
|
||||||
|
public static final String RETAIN_CYCLE = "RETAIN_CYCLE";
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static DebuggableTemporaryFolder folder =
|
||||||
|
new DebuggableTemporaryFolder();
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void runInfer() throws InterruptedException, IOException {
|
||||||
|
inferCmd = InferRunner.createObjCInferCommand(folder, FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInferRunsOnStrongCycleThenRCIsFound()
|
||||||
|
throws InterruptedException, IOException, InferException {
|
||||||
|
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
|
||||||
|
String[] procedures = {
|
||||||
|
"main",
|
||||||
|
};
|
||||||
|
assertThat(
|
||||||
|
"Results should contain the expected retain cycles",
|
||||||
|
inferResults,
|
||||||
|
containsExactly(
|
||||||
|
RETAIN_CYCLE,
|
||||||
|
FILE,
|
||||||
|
procedures
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue