Translate headers located inside analyzed project

Summary:public
Translate headers every time they are included provided that they are located inside project_root directory.
While this is suboptimal (we might end up translating same header many times), doing it exactly once
is hard due to parallel compilation and template instantiations

Reviewed By: dulmarod

Differential Revision: D2916799

fb-gh-sync-id: 93b72c4
shipit-source-id: 93b72c4
master
Andrzej Kotulski 9 years ago committed by facebook-github-bot-1
parent a6d7bbb38b
commit f703d780da

@ -75,17 +75,28 @@ let clang_to_sil_location clang_loc procdesc_opt =
Location.{line; col; file; nLOC} Location.{line; col; file; nLOC}
let should_translate (loc_start, loc_end) = let should_translate (loc_start, loc_end) =
let map_file_of pred loc = let map_path_of pred loc =
match loc.Clang_ast_t.sl_file with match loc.Clang_ast_t.sl_file with
| Some f -> pred (source_file_from_path f) | Some f -> pred f
| None -> false | None -> false
in in
let map_file_of pred loc =
let path_pred path = pred (source_file_from_path path) in
map_path_of path_pred loc
in
let equal_current_source file = let equal_current_source file =
DB.source_file_equal file !DB.current_source DB.source_file_equal file !DB.current_source
in in
let file_in_project file = match !Config.project_root with
| Some root -> Utils.string_is_prefix root file
| None -> false
in
let file_in_project = map_path_of file_in_project loc_end
|| map_path_of file_in_project loc_start in
equal_current_source !curr_file equal_current_source !curr_file
|| map_file_of equal_current_source loc_end || map_file_of equal_current_source loc_end
|| map_file_of equal_current_source loc_start || map_file_of equal_current_source loc_start
|| (!CFrontend_config.testing_mode && file_in_project)
let should_translate_lib source_range = let should_translate_lib source_range =
not !CFrontend_config.no_translate_libs not !CFrontend_config.no_translate_libs

@ -16,7 +16,6 @@ module L = Logging
open CFrontend_utils open CFrontend_utils
let arg_desc = let arg_desc =
Config.dotty_cfg_libs := false; (* default behavior for this frontend *)
let desc = let desc =
(Utils.arg_desc_filter ["-results_dir"] Utils.base_arg_desc) @ (Utils.arg_desc_filter ["-results_dir"] Utils.base_arg_desc) @
[ [
@ -35,8 +34,8 @@ let arg_desc =
Some "file", Some "file",
"AST file for the translation" "AST file for the translation"
; ;
"-dotty_cfg_libs", "-dotty_no_cfg_libs",
Arg.Unit (fun _ -> Config.dotty_cfg_libs := true), Arg.Unit (fun _ -> Config.dotty_cfg_libs := false),
None, None,
"Prints the cfg of the code coming from the libraries" "Prints the cfg of the code coming from the libraries"
; ;

@ -0,0 +1,22 @@
/*
* Copyright (c) 2016 - 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.
*/
struct A {
int div0() { return 1 / 0; }
};
template<class T>
struct B {
int div0() { return 1 / 0; }
};
int div0_fun() { return 1 / 0; }
template<class T>
int div0_templ() { return 1 / 0; }

@ -0,0 +1,46 @@
digraph iCFG {
12 [label="12: DeclStmt \n _fun_A_A(&a:class A *) [line 13]\n " shape="box"]
12 -> 11 ;
11 [label="11: Return Stmt \n n$0=_fun_A_get0(&a:class A &) [line 14]\n *&return:int =(1 / n$0) [line 14]\n REMOVE_TEMPS(n$0); [line 14]\n NULLIFY(&a,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"]
11 -> 10 ;
10 [label="10: Exit div0_a \n " color=yellow style=filled]
9 [label="9: Start div0_a\nFormals: \nLocals: a:class A \n DECLARE_LOCALS(&return,&a); [line 12]\n " color=yellow style=filled]
9 -> 12 ;
8 [label="8: Return Stmt \n *&return:int =(1 / 0) [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"]
8 -> 7 ;
7 [label="7: Exit div0_fun \n " color=yellow style=filled]
6 [label="6: Start div0_fun\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 19]\n " color=yellow style=filled]
6 -> 8 ;
5 [label="5: Exit A_A \n " color=yellow style=filled]
4 [label="4: Start A_A\nFormals: this:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 10]\n NULLIFY(&this,false); [line 10]\n " color=yellow style=filled]
4 -> 5 ;
3 [label="3: Return Stmt \n *&return:int =0 [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit A_get0 \n " color=yellow style=filled]
1 [label="1: Start A_get0\nFormals: this:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 11]\n NULLIFY(&this,false); [line 11]\n " color=yellow style=filled]
1 -> 3 ;
}

@ -0,0 +1,10 @@
/*
* Copyright (c) 2016 - 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.
*/
#include "header.h"

@ -0,0 +1,24 @@
digraph iCFG {
6 [label="6: Return Stmt \n *&return:int =(1 / 0) [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"]
6 -> 5 ;
5 [label="5: Exit div0_fun \n " color=yellow style=filled]
4 [label="4: Start div0_fun\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 19]\n " color=yellow style=filled]
4 -> 6 ;
3 [label="3: Return Stmt \n *&return:int =(1 / 0) [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit A_div0 \n " color=yellow style=filled]
1 [label="1: Start A_div0\nFormals: this:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 11]\n NULLIFY(&this,false); [line 11]\n " color=yellow style=filled]
1 -> 3 ;
}

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 - 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.
*/
#include "header.h"
// instantiate templates to produce bug reports for them
void div0_B_int() {
B<int> b;
b.div0();
}
void div0_B_A() {
B<A> b;
b.div0();
}
void div0_templ_int() {
div0_templ<int>();
}
int div0_templ_A() {
div0_templ<A>();
}

@ -0,0 +1,134 @@
digraph iCFG {
36 [label="36: Call _fun_div0_templ<A> \n n$0=_fun_div0_templ<A>() [line 28]\n REMOVE_TEMPS(n$0); [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"]
36 -> 35 ;
35 [label="35: Exit div0_templ_A \n " color=yellow style=filled]
34 [label="34: Start div0_templ_A\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 27]\n " color=yellow style=filled]
34 -> 36 ;
33 [label="33: Call _fun_div0_templ<int> \n n$0=_fun_div0_templ<int>() [line 24]\n REMOVE_TEMPS(n$0); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"]
33 -> 32 ;
32 [label="32: Exit div0_templ_int \n " color=yellow style=filled]
31 [label="31: Start div0_templ_int\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 23]\n " color=yellow style=filled]
31 -> 33 ;
30 [label="30: DeclStmt \n _fun_B<A>_B(&b:class B<A> *) [line 19]\n " shape="box"]
30 -> 29 ;
29 [label="29: Call _fun_B<A>_div0 \n n$0=_fun_B<A>_div0(&b:class B<A> &) [line 20]\n REMOVE_TEMPS(n$0); [line 20]\n NULLIFY(&b,false); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="box"]
29 -> 28 ;
28 [label="28: Exit div0_B_A \n " color=yellow style=filled]
27 [label="27: Start div0_B_A\nFormals: \nLocals: b:class B<A> \n DECLARE_LOCALS(&return,&b); [line 18]\n " color=yellow style=filled]
27 -> 30 ;
26 [label="26: DeclStmt \n _fun_B<int>_B(&b:class B<int> *) [line 14]\n " shape="box"]
26 -> 25 ;
25 [label="25: Call _fun_B<int>_div0 \n n$0=_fun_B<int>_div0(&b:class B<int> &) [line 15]\n REMOVE_TEMPS(n$0); [line 15]\n NULLIFY(&b,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"]
25 -> 24 ;
24 [label="24: Exit div0_B_int \n " color=yellow style=filled]
23 [label="23: Start div0_B_int\nFormals: \nLocals: b:class B<int> \n DECLARE_LOCALS(&return,&b); [line 13]\n " color=yellow style=filled]
23 -> 26 ;
22 [label="22: Return Stmt \n *&return:int =(1 / 0) [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"]
22 -> 21 ;
21 [label="21: Exit div0_templ<A> \n " color=yellow style=filled]
20 [label="20: Start div0_templ<A>\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 22]\n " color=yellow style=filled]
20 -> 22 ;
19 [label="19: Return Stmt \n *&return:int =(1 / 0) [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"]
19 -> 18 ;
18 [label="18: Exit div0_templ<int> \n " color=yellow style=filled]
17 [label="17: Start div0_templ<int>\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 22]\n " color=yellow style=filled]
17 -> 19 ;
16 [label="16: Return Stmt \n *&return:int =(1 / 0) [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"]
16 -> 15 ;
15 [label="15: Exit div0_fun \n " color=yellow style=filled]
14 [label="14: Start div0_fun\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 19]\n " color=yellow style=filled]
14 -> 16 ;
13 [label="13: Exit B<A>_B \n " color=yellow style=filled]
12 [label="12: Start B<A>_B\nFormals: this:class B<A> *\nLocals: \n DECLARE_LOCALS(&return); [line 15]\n NULLIFY(&this,false); [line 15]\n " color=yellow style=filled]
12 -> 13 ;
11 [label="11: Return Stmt \n *&return:int =(1 / 0) [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"]
11 -> 10 ;
10 [label="10: Exit B<A>_div0 \n " color=yellow style=filled]
9 [label="9: Start B<A>_div0\nFormals: this:class B<A> *\nLocals: \n DECLARE_LOCALS(&return); [line 16]\n NULLIFY(&this,false); [line 16]\n " color=yellow style=filled]
9 -> 11 ;
8 [label="8: Exit B<int>_B \n " color=yellow style=filled]
7 [label="7: Start B<int>_B\nFormals: this:class B<int> *\nLocals: \n DECLARE_LOCALS(&return); [line 15]\n NULLIFY(&this,false); [line 15]\n " color=yellow style=filled]
7 -> 8 ;
6 [label="6: Return Stmt \n *&return:int =(1 / 0) [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"]
6 -> 5 ;
5 [label="5: Exit B<int>_div0 \n " color=yellow style=filled]
4 [label="4: Start B<int>_div0\nFormals: this:class B<int> *\nLocals: \n DECLARE_LOCALS(&return); [line 16]\n NULLIFY(&this,false); [line 16]\n " color=yellow style=filled]
4 -> 6 ;
3 [label="3: Return Stmt \n *&return:int =(1 / 0) [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit A_div0 \n " color=yellow style=filled]
1 [label="1: Start A_div0\nFormals: this:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 11]\n NULLIFY(&this,false); [line 11]\n " color=yellow style=filled]
1 -> 3 ;
}

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
#include <iostream>
using namespace std; using namespace std;
namespace foo namespace foo

@ -0,0 +1,66 @@
/*
* Copyright (c) 2016 - 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.cpp;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.ResultContainsExactly.containsExactly;
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 IncludeHeaderNoTemplTest {
public static final String FILE =
"infer/tests/codetoanalyze/cpp/frontend/include_header/include_only.cpp";
public static final String HEADER =
"infer/tests/codetoanalyze/cpp/frontend/include_header/header.h";
private static ImmutableList<String> inferCmd;
public static final String DIVIDE_BY_ZERO = "DIVIDE_BY_ZERO";
@ClassRule
public static DebuggableTemporaryFolder folder =
new DebuggableTemporaryFolder();
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createCPPInferCommand(folder, FILE);
}
@Test
public void whenInferRunsOnDiv0MethodsErrorIsFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferCPP(inferCmd);
String[] procedures = {
"A_div0",
"div0_fun",
};
assertThat(
"Results should contain the expected divide by zero",
inferResults,
containsExactly(
DIVIDE_BY_ZERO,
HEADER,
procedures
)
);
}
}

@ -0,0 +1,70 @@
/*
* Copyright (c) 2016 - 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.cpp;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.ResultContainsExactly.containsExactly;
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 IncludeHeaderTemplTest {
public static final String FILE =
"infer/tests/codetoanalyze/cpp/frontend/include_header/include_templ.cpp";
public static final String HEADER =
"infer/tests/codetoanalyze/cpp/frontend/include_header/header.h";
private static ImmutableList<String> inferCmd;
public static final String DIVIDE_BY_ZERO = "DIVIDE_BY_ZERO";
@ClassRule
public static DebuggableTemporaryFolder folder =
new DebuggableTemporaryFolder();
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createCPPInferCommand(folder, FILE);
}
@Test
public void whenInferRunsOnDiv0MethodsErrorIsFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferCPP(inferCmd);
String[] procedures = {
"A_div0",
"B<int>_div0",
"B<A>_div0",
"div0_fun",
"div0_templ<int>",
"div0_templ<A>",
};
assertThat(
"Results should contain the expected divide by zero",
inferResults,
containsExactly(
DIVIDE_BY_ZERO,
HEADER,
procedures
)
);
}
}

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016 - 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 frontend.cpp;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import utils.DebuggableTemporaryFolder;
import utils.InferException;
import utils.ClangFrontendUtils;
public class IncludeHeaderTest {
String basePath = "infer/tests/codetoanalyze/cpp/frontend/include_header/";
@Rule
public DebuggableTemporaryFolder folder = new DebuggableTemporaryFolder();
void frontendTest(String fileRelative) throws InterruptedException, IOException, InferException {
ClangFrontendUtils.createAndCompareCppDotFiles(folder, basePath + fileRelative);
}
@Test
public void testIncludeOnlyDotFilesMatch()
throws InterruptedException, IOException, InferException {
frontendTest("include_only.cpp");
}
@Test
public void testIncludeTemplDotFilesMatch()
throws InterruptedException, IOException, InferException {
frontendTest("include_templ.cpp");
}
}
Loading…
Cancel
Save