1 // RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s 2 3 // Tests that macros and non-macro clones aren't mixed into the same hash 4 // group. This is currently necessary as all clones in a hash group need 5 // to have the same complexity value. Macros have smaller complexity values 6 // and need to be in their own hash group. 7 8 int foo(int a) { // expected-warning{{Duplicate code detected}} 9 a = a + 1; 10 a = a + 1 / 1; 11 a = a + 1 + 1 + 1; 12 a = a + 1 - 1 + 1 + 1; 13 a = a + 1 * 1 + 1 + 1 + 1; 14 a = a + 1 / 1 + 1 + 1 + 1; 15 return a; 16 } 17 18 int fooClone(int a) { // expected-note{{Similar code here}} 19 a = a + 1; 20 a = a + 1 / 1; 21 a = a + 1 + 1 + 1; 22 a = a + 1 - 1 + 1 + 1; 23 a = a + 1 * 1 + 1 + 1 + 1; 24 a = a + 1 / 1 + 1 + 1 + 1; 25 return a; 26 } 27 28 // Below is the same AST as above but this time generated with macros. The 29 // clones below should land in their own hash group for the reasons given above. 30 31 #define ASSIGN(T, V) T = T + V 32 33 int macro(int a) { // expected-warning{{Duplicate code detected}} 34 ASSIGN(a, 1); 35 ASSIGN(a, 1 / 1); 36 ASSIGN(a, 1 + 1 + 1); 37 ASSIGN(a, 1 - 1 + 1 + 1); 38 ASSIGN(a, 1 * 1 + 1 + 1 + 1); 39 ASSIGN(a, 1 / 1 + 1 + 1 + 1); 40 return a; 41 } 42 43 int macroClone(int a) { // expected-note{{Similar code here}} 44 ASSIGN(a, 1); 45 ASSIGN(a, 1 / 1); 46 ASSIGN(a, 1 + 1 + 1); 47 ASSIGN(a, 1 - 1 + 1 + 1); 48 ASSIGN(a, 1 * 1 + 1 + 1 + 1); 49 ASSIGN(a, 1 / 1 + 1 + 1 + 1); 50 return a; 51 } 52 53 // FIXME: Macros with empty definitions in the AST are currently ignored. 54 55 #define EMPTY 56 57 int fooFalsePositiveClone(int a) { // expected-note{{Similar code here}} 58 a = EMPTY a + 1; 59 a = a + 1 / 1; 60 a = a + 1 + 1 + 1; 61 a = a + 1 - 1 + 1 + 1; 62 a = a + 1 * 1 + 1 + 1 + 1; 63 a = a + 1 / 1 + 1 + 1 + 1; 64 return a; 65 } 66 67 68