Summary: When clang instantiates template function with argument pack, it will give the same name to all parameters coming from the pack. To avoid name collisions, always add index of argument's position to mangled part of the variable. Seemingly unrelated changes are to make existing tests pass (don't use simple variable name where it matters) Reviewed By: dulmarod Differential Revision: D3503608 fbshipit-source-id: 794093amaster
parent
1420cabac5
commit
e46cddb52b
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// div(a,b,c,d) = 1/a + 1/b + 1/c + 1/d;
|
||||
int div(int d) { return 1 / d; }
|
||||
template <typename... Args>
|
||||
int div(int v, Args... args) {
|
||||
return 1 / v + div(args...);
|
||||
}
|
||||
|
||||
int div0_1arg() { return div(0); }
|
||||
|
||||
int div0_3args1() { return div(0, 2, 3); }
|
||||
int div0_3args2() { return div(1, 0, 3); }
|
||||
int div0_3args3() { return div(1, 2, 0); }
|
||||
int div0_3args4() { return div(1, 0, 0); }
|
||||
int div0_10args() { return div(1, 2, 3, 4, 5, 6, 7, 0, 9, 10); }
|
||||
|
||||
int no_div0_3_args() { return div(1, 2, 3); }
|
||||
int no_div0_10args() { return div(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); }
|
@ -0,0 +1,201 @@
|
||||
/* @generated */
|
||||
digraph iCFG {
|
||||
54 [label="54: Return Stmt \n n$0=_fun_div<5ae447456b906d06>(1:int ,2:int ,3:int ,4:int ,5:int ,6:int ,7:int ,8:int ,9:int ,10:int ) [line 26]\n *&return:int =n$0 [line 26]\n " shape="box"]
|
||||
|
||||
|
||||
54 -> 53 ;
|
||||
53 [label="53: Exit no_div0_10args \n " color=yellow style=filled]
|
||||
|
||||
|
||||
52 [label="52: Start no_div0_10args\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 26]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
52 -> 54 ;
|
||||
51 [label="51: Return Stmt \n n$0=_fun_div<int, int>(1:int ,2:int ,3:int ) [line 25]\n *&return:int =n$0 [line 25]\n " shape="box"]
|
||||
|
||||
|
||||
51 -> 50 ;
|
||||
50 [label="50: Exit no_div0_3_args \n " color=yellow style=filled]
|
||||
|
||||
|
||||
49 [label="49: Start no_div0_3_args\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
49 -> 51 ;
|
||||
48 [label="48: Return Stmt \n n$0=_fun_div<5ae447456b906d06>(1:int ,2:int ,3:int ,4:int ,5:int ,6:int ,7:int ,0:int ,9:int ,10:int ) [line 23]\n *&return:int =n$0 [line 23]\n " shape="box"]
|
||||
|
||||
|
||||
48 -> 47 ;
|
||||
47 [label="47: Exit div0_10args \n " color=yellow style=filled]
|
||||
|
||||
|
||||
46 [label="46: Start div0_10args\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 23]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
46 -> 48 ;
|
||||
45 [label="45: Return Stmt \n n$0=_fun_div<int, int>(1:int ,0:int ,0:int ) [line 22]\n *&return:int =n$0 [line 22]\n " shape="box"]
|
||||
|
||||
|
||||
45 -> 44 ;
|
||||
44 [label="44: Exit div0_3args4 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
43 [label="43: Start div0_3args4\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 22]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
43 -> 45 ;
|
||||
42 [label="42: Return Stmt \n n$0=_fun_div<int, int>(1:int ,2:int ,0:int ) [line 21]\n *&return:int =n$0 [line 21]\n " shape="box"]
|
||||
|
||||
|
||||
42 -> 41 ;
|
||||
41 [label="41: Exit div0_3args3 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
40 [label="40: Start div0_3args3\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
40 -> 42 ;
|
||||
39 [label="39: Return Stmt \n n$0=_fun_div<int, int>(1:int ,0:int ,3:int ) [line 20]\n *&return:int =n$0 [line 20]\n " shape="box"]
|
||||
|
||||
|
||||
39 -> 38 ;
|
||||
38 [label="38: Exit div0_3args2 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
37 [label="37: Start div0_3args2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 20]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
37 -> 39 ;
|
||||
36 [label="36: Return Stmt \n n$0=_fun_div<int, int>(0:int ,2:int ,3:int ) [line 19]\n *&return:int =n$0 [line 19]\n " shape="box"]
|
||||
|
||||
|
||||
36 -> 35 ;
|
||||
35 [label="35: Exit div0_3args1 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
34 [label="34: Start div0_3args1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 19]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
34 -> 36 ;
|
||||
33 [label="33: Return Stmt \n n$0=_fun_div(0:int ) [line 17]\n *&return:int =n$0 [line 17]\n " shape="box"]
|
||||
|
||||
|
||||
33 -> 32 ;
|
||||
32 [label="32: Exit div0_1arg \n " color=yellow style=filled]
|
||||
|
||||
|
||||
31 [label="31: Start div0_1arg\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
31 -> 33 ;
|
||||
30 [label="30: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=*&args:int [line 14]\n n$5=*&args:int [line 14]\n n$6=*&args:int [line 14]\n n$7=*&args:int [line 14]\n n$8=*&args:int [line 14]\n n$9=*&args:int [line 14]\n n$10=_fun_div<int, int, int, int, int, int, int, int>(n$1:int ,n$2:int ,n$3:int ,n$4:int ,n$5:int ,n$6:int ,n$7:int ,n$8:int ,n$9:int ) [line 14]\n *&return:int =((1 / n$0) + n$10) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
30 -> 11 ;
|
||||
29 [label="29: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=*&args:int [line 14]\n n$5=*&args:int [line 14]\n n$6=*&args:int [line 14]\n n$7=*&args:int [line 14]\n n$8=*&args:int [line 14]\n n$9=_fun_div<int, int, int, int, int, int, int>(n$1:int ,n$2:int ,n$3:int ,n$4:int ,n$5:int ,n$6:int ,n$7:int ,n$8:int ) [line 14]\n *&return:int =((1 / n$0) + n$9) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
29 -> 13 ;
|
||||
28 [label="28: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=*&args:int [line 14]\n n$5=*&args:int [line 14]\n n$6=*&args:int [line 14]\n n$7=*&args:int [line 14]\n n$8=_fun_div<int, int, int, int, int, int>(n$1:int ,n$2:int ,n$3:int ,n$4:int ,n$5:int ,n$6:int ,n$7:int ) [line 14]\n *&return:int =((1 / n$0) + n$8) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
28 -> 15 ;
|
||||
27 [label="27: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=*&args:int [line 14]\n n$5=*&args:int [line 14]\n n$6=*&args:int [line 14]\n n$7=_fun_div<int, int, int, int, int>(n$1:int ,n$2:int ,n$3:int ,n$4:int ,n$5:int ,n$6:int ) [line 14]\n *&return:int =((1 / n$0) + n$7) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
27 -> 17 ;
|
||||
26 [label="26: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=*&args:int [line 14]\n n$5=*&args:int [line 14]\n n$6=_fun_div<int, int, int, int>(n$1:int ,n$2:int ,n$3:int ,n$4:int ,n$5:int ) [line 14]\n *&return:int =((1 / n$0) + n$6) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
26 -> 19 ;
|
||||
25 [label="25: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=*&args:int [line 14]\n n$5=_fun_div<int, int, int>(n$1:int ,n$2:int ,n$3:int ,n$4:int ) [line 14]\n *&return:int =((1 / n$0) + n$5) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
25 -> 21 ;
|
||||
24 [label="24: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=*&args:int [line 14]\n n$4=_fun_div<int, int>(n$1:int ,n$2:int ,n$3:int ) [line 14]\n *&return:int =((1 / n$0) + n$4) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
24 -> 23 ;
|
||||
23 [label="23: Exit div<int, int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
22 [label="22: Start div<int, int, int>\nFormals: v:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
22 -> 24 ;
|
||||
21 [label="21: Exit div<int, int, int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
20 [label="20: Start div<int, int, int, int>\nFormals: v:int args:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
20 -> 25 ;
|
||||
19 [label="19: Exit div<int, int, int, int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
18 [label="18: Start div<int, int, int, int, int>\nFormals: v:int args:int args:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
18 -> 26 ;
|
||||
17 [label="17: Exit div<int, int, int, int, int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
16 [label="16: Start div<int, int, int, int, int, int>\nFormals: v:int args:int args:int args:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
16 -> 27 ;
|
||||
15 [label="15: Exit div<int, int, int, int, int, int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
14 [label="14: Start div<int, int, int, int, int, int, int>\nFormals: v:int args:int args:int args:int args:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
14 -> 28 ;
|
||||
13 [label="13: Exit div<int, int, int, int, int, int, int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
12 [label="12: Start div<int, int, int, int, int, int, int, int>\nFormals: v:int args:int args:int args:int args:int args:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
12 -> 29 ;
|
||||
11 [label="11: Exit div<5ae447456b906d06> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
10 [label="10: Start div<5ae447456b906d06>\nFormals: v:int args:int args:int args:int args:int args:int args:int args:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
10 -> 30 ;
|
||||
9 [label="9: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=*&args:int [line 14]\n n$3=_fun_div<int>(n$1:int ,n$2:int ) [line 14]\n *&return:int =((1 / n$0) + n$3) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
9 -> 5 ;
|
||||
8 [label="8: Return Stmt \n n$0=*&v:int [line 14]\n n$1=*&args:int [line 14]\n n$2=_fun_div(n$1:int ) [line 14]\n *&return:int =((1 / n$0) + n$2) [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
8 -> 7 ;
|
||||
7 [label="7: Exit div<int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
6 [label="6: Start div<int>\nFormals: v:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
6 -> 8 ;
|
||||
5 [label="5: Exit div<int, int> \n " color=yellow style=filled]
|
||||
|
||||
|
||||
4 [label="4: Start div<int, int>\nFormals: v:int args:int args:int \nLocals: \n DECLARE_LOCALS(&return); [line 13]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
4 -> 9 ;
|
||||
3 [label="3: Return Stmt \n n$0=*&d:int [line 11]\n *&return:int =(1 / n$0) [line 11]\n " shape="box"]
|
||||
|
||||
|
||||
3 -> 2 ;
|
||||
2 [label="2: Exit div \n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 [label="1: Start div\nFormals: d:int \nLocals: \n DECLARE_LOCALS(&return); [line 11]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 -> 3 ;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 TemplateFunctionPackTest {
|
||||
|
||||
public static final String FILE =
|
||||
"infer/tests/codetoanalyze/cpp/frontend/templates/function_pack.cpp";
|
||||
|
||||
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 = {
|
||||
"div0_1arg",
|
||||
"div0_3args1",
|
||||
"div0_3args2",
|
||||
"div0_3args3",
|
||||
"div0_3args4",
|
||||
"div0_10args",
|
||||
};
|
||||
assertThat(
|
||||
"Results should contain the expected divide by zero",
|
||||
inferResults,
|
||||
containsExactly(
|
||||
DIVIDE_BY_ZERO,
|
||||
FILE,
|
||||
procedures
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue