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,16 +895,12 @@ let ident_partial_meet (id1: Ident.t) (id2: Ident.t) =
(** {2 Join and Meet for Exps} *)
let const_partial_join c1 c2 =
if (Sil.const_equal c1 c2) then Sil.Const c1
else match c1, c2 with
| 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)
| _ ->
if (!Config.abs_val >= 2) then FreshVarExp.get_fresh_exp (Sil.Const c1) (Sil.Const c2)
else (L.d_strln "failure reason 19"; raise IList.Fail)
if Sil.const_equal c1 c2 then Sil.Const c1
else if Sil.const_kind_equal c1 c2 then
(L.d_strln "failure reason 18"; raise IList.Fail)
else if !Config.abs_val >= 2 then
FreshVarExp.get_fresh_exp (Sil.Const c1) (Sil.Const c2)
else (L.d_strln "failure reason 19"; raise IList.Fail)
let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
(* L.d_str "exp_partial_join "; Sil.d_exp e1; L.d_str " "; Sil.d_exp e2; L.d_ln (); *)

@ -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
Clang_ast_t.CallExpr (stmt_info, cast:: parameters, expr_info_call)
(* For a of type NSArray* Translate *)
(* [a enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL * stop) { *)
(* body_block *)
(* }; *)
(* ]; *)
(* as follows: *)
(* NSArray *objects = a; *)
(* void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL* )= ^(id object, NSUInteger idx, BOOL* stop) { *)
(* body_block *)
(* }; *)
(* 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); *)
(* *)
(* For a of type NSArray* Translate
[a enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL * stop) {
body_block
};
];
as follows:
NSArray *objects = a;
void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL* ) =
^(id object, NSUInteger idx, BOOL* stop) {
body_block
};
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);
*)
let translate_block_enumerate block_name stmt_info stmt_list ei =
let rec get_name_pointers lp =
@ -490,7 +491,7 @@ let translate_block_enumerate block_name stmt_info stmt_list ei =
| Clang_ast_t.ImplicitCastExpr (_, _, ei, _) -> ei
| _ -> assert false in
(* id object= objects[idx]; *)
(* id object = objects[idx]; *)
let build_object_DeclStmt pobj decl_ref_expr_array decl_ref_expr_idx tp_idx =
let open Clang_ast_t in
match pobj with

@ -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