Fixed FP for blocks used in loops generated by join operator

Reviewed By: dulmarod

Differential Revision: D2765074

fb-gh-sync-id: 5362f91
master
Dino Distefano 9 years ago committed by facebook-github-bot-1
parent d48f33c1c3
commit 4feb93e91c

@ -895,15 +895,11 @@ let ident_partial_meet (id1: Ident.t) (id2: Ident.t) =
(** {2 Join and Meet for Exps} *) (** {2 Join and Meet for Exps} *)
let const_partial_join c1 c2 = let const_partial_join c1 c2 =
if (Sil.const_equal c1 c2) then Sil.Const c1 if Sil.const_equal c1 c2 then Sil.Const c1
else match c1, c2 with else if Sil.const_kind_equal c1 c2 then
| Sil.Cfun _, Sil.Cfun _
| Sil.Cstr _, Sil.Cstr _
| Sil.Cclass _, Sil.Cclass _
| Sil.Cattribute _, Sil.Cattribute _ ->
(L.d_strln "failure reason 18"; raise IList.Fail) (L.d_strln "failure reason 18"; raise IList.Fail)
| _ -> else if !Config.abs_val >= 2 then
if (!Config.abs_val >= 2) then FreshVarExp.get_fresh_exp (Sil.Const c1) (Sil.Const c2) FreshVarExp.get_fresh_exp (Sil.Const c1) (Sil.Const c2)
else (L.d_strln "failure reason 19"; raise IList.Fail) else (L.d_strln "failure reason 19"; raise IList.Fail)
let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp = let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =

@ -374,28 +374,29 @@ let create_call stmt_info decl_pointer function_name tp parameters =
let cast = create_implicit_cast_expr (fresh_stmt_info stmt_info) [decl_ref_exp] tp `FunctionToPointerDecay in let cast = create_implicit_cast_expr (fresh_stmt_info stmt_info) [decl_ref_exp] tp `FunctionToPointerDecay in
Clang_ast_t.CallExpr (stmt_info, cast:: parameters, expr_info_call) Clang_ast_t.CallExpr (stmt_info, cast:: parameters, expr_info_call)
(* For a of type NSArray* Translate *) (* For a of type NSArray* Translate
(* [a enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL * stop) { *) [a enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL * stop) {
(* body_block *) body_block
(* }; *) };
(* ]; *) ];
(* as follows: *) as follows:
(* NSArray *objects = a; *) NSArray *objects = a;
(* void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL* )= ^(id object, NSUInteger idx, BOOL* stop) { *) void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL* ) =
(* body_block *) ^(id object, NSUInteger idx, BOOL* stop) {
(* }; *) body_block
(* BOOL *stop = malloc(sizeof(BOOL)); *) };
(* *stop = NO; *) BOOL *stop = malloc(sizeof(BOOL));
*stop = NO;
(* for (NSUInteger idx=0; idx<objects.count; idx++) { *)
(* id object= objects[idx]; *) for (NSUInteger idx=0; idx<objects.count; idx++) {
(* enumerateObjectsUsingBlock(object, idx, stop); *) id object= objects[idx];
(* if ( *stop ==YES) break; *) enumerateObjectsUsingBlock(object, idx, stop);
(* } *) if ( *stop ==YES) break;
(* free(stop); *) }
(* *) free(stop);
*)
let translate_block_enumerate block_name stmt_info stmt_list ei = let translate_block_enumerate block_name stmt_info stmt_list ei =
let rec get_name_pointers lp = let rec get_name_pointers lp =

@ -0,0 +1,66 @@
/*
* 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>
@interface B : NSObject
+ foo:(id) obj;
@end
@implementation B
+ (B*) foo:(id) obj
{
return obj;
}
@end
@interface A : NSObject
- (NSMutableArray *) allResultsList: (NSArray *) allResults;
@end
@implementation A
// From a diff
- (NSMutableArray *) allResultsList: (NSArray *) allResults {
NSMutableArray *resultsList = [[NSMutableArray alloc] init];
[allResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id *result = [B foo:obj];
if (result != nil) {
[resultsList addObject:result];
}
}];
return resultsList;
}
// How that code is translated in INFER
- (void) foo1: (NSArray*) a {
NSArray *objects = a;
NSMutableArray *resultsList = [[NSMutableArray alloc] init];
void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL* ) =
^(id obj, NSUInteger idx, BOOL* stop) {
id *result = [B foo:obj];
if (result != nil) {
[resultsList addObject:result];
}
};
BOOL *stop = malloc(sizeof(BOOL));
*stop = NO;
for (NSUInteger idx = 0; idx < objects.count; idx++) {
id object = objects[idx];
enumerateObjectsUsingBlock(object, idx, stop);
if ( *stop == YES) break;
}
free(stop);
}
@end

@ -0,0 +1,73 @@
/*
* 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.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 NullParamTest {
public static final String block_file =
"infer/tests/codetoanalyze/objc/errors/npe/blockenum.m";
private static ImmutableList<String> inferCmd;
public static final String PARAMETER_NOT_NULL_CHECKED = "PARAMETER_NOT_NULL_CHECKED";
@ClassRule
public static DebuggableTemporaryFolder folder =
new DebuggableTemporaryFolder();
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommand(
folder,
block_file
);
}
@Test
public void whenInferRunsOnFoo1ParameterNilIsNotFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
assertThat(
"Results should not contain memory leak",
inferResults,
doesNotContain(
PARAMETER_NOT_NULL_CHECKED,
block_file,
"foo1:"));
}
@Test
public void whenInferRunsOnAllResultsListParameterNilIsNotFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
assertThat(
"Results should not contain memory leak",
inferResults,
doesNotContain(
PARAMETER_NOT_NULL_CHECKED,
block_file,
"allResultsList:"));
}
}
Loading…
Cancel
Save