Raphael Isemann | 561f0de | 2017-09-04 05:56:36 +0000 | [diff] [blame] | 1 | // RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s |
Artem Dergachev | 78692ea | 2016-08-02 12:21:09 +0000 | [diff] [blame] | 2 | |
| 3 | // expected-no-diagnostics |
| 4 | |
| 5 | bool a(); |
| 6 | bool b(); |
| 7 | |
| 8 | // Calls method a with some extra code to pass the minimum complexity |
| 9 | bool foo1(int x) { |
| 10 | if (x > 0) |
| 11 | return false; |
| 12 | else if (x < 0) |
| 13 | return a(); |
| 14 | return true; |
| 15 | } |
| 16 | |
| 17 | // Calls method b with some extra code to pass the minimum complexity |
| 18 | bool foo2(int x) { |
| 19 | if (x > 0) |
| 20 | return false; |
| 21 | else if (x < 0) |
| 22 | return b(); |
| 23 | return true; |
| 24 | } |
Artem Dergachev | cad1514 | 2016-08-10 16:25:16 +0000 | [diff] [blame] | 25 | |
| 26 | // Test that we don't crash on function pointer calls |
| 27 | |
| 28 | bool (*funcPtr)(int); |
| 29 | |
| 30 | bool fooPtr1(int x) { |
| 31 | if (x > 0) |
| 32 | return false; |
| 33 | else if (x < 0) |
| 34 | return funcPtr(1); |
| 35 | return true; |
| 36 | } |
Artem Dergachev | 5183888 | 2016-08-20 09:57:21 +0000 | [diff] [blame] | 37 | |
| 38 | // Test that we respect the template arguments of function templates |
| 39 | |
| 40 | template<typename T, unsigned N> |
| 41 | bool templateFunc() { unsigned i = N; return false; } |
| 42 | |
| 43 | bool fooTemplate1(int x) { |
| 44 | if (x > 0) |
| 45 | return false; |
| 46 | else if (x < 0) |
| 47 | return templateFunc<int, 1>(); |
| 48 | return true; |
| 49 | } |
| 50 | |
| 51 | bool fooTemplate2(int x) { |
| 52 | if (x > 0) |
| 53 | return false; |
| 54 | else if (x < 0) |
| 55 | return templateFunc<long, 1>(); |
| 56 | return true; |
| 57 | } |
| 58 | |
| 59 | bool fooTemplate3(int x) { |
| 60 | if (x > 0) |
| 61 | return false; |
| 62 | else if (x < 0) |
| 63 | return templateFunc<long, 2>(); |
| 64 | return true; |
| 65 | } |
| 66 | |
| 67 | // Test that we don't just concatenate the template arguments into a string |
| 68 | // without having any padding between them (e.g. foo<X, XX>() != foo<XX, X>()). |
| 69 | |
| 70 | class X {}; |
| 71 | class XX {}; |
| 72 | |
| 73 | template<typename T1, typename T2> |
| 74 | bool templatePaddingFunc() { return false; } |
| 75 | |
| 76 | bool fooTemplatePadding1(int x) { |
| 77 | if (x > 0) |
| 78 | return false; |
| 79 | else if (x < 0) |
| 80 | return templatePaddingFunc<X, XX>(); |
| 81 | return true; |
| 82 | } |
| 83 | |
| 84 | bool fooTemplatePadding2(int x) { |
| 85 | if (x > 0) |
| 86 | return false; |
| 87 | else if (x < 0) |
| 88 | return templatePaddingFunc<XX, X>(); |
| 89 | return true; |
| 90 | } |
Artem Dergachev | 5f94b08 | 2016-08-23 16:42:00 +0000 | [diff] [blame] | 91 | |
| 92 | // Test that we don't crash on member functions of template instantiations. |
| 93 | |
| 94 | template<typename T> |
| 95 | struct A { |
| 96 | void foo(T t) {} |
| 97 | }; |
| 98 | |
| 99 | void fooTestInstantiation() { |
| 100 | A<int> a; |
| 101 | a.foo(1); |
| 102 | } |