xref: /llvm-project/clang/test/Analysis/copypaste/call.cpp (revision 561f0de6d96eff6efc53e6e8b07bc9408304b381)
1*561f0de6SRaphael Isemann // RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
278692ea5SArtem Dergachev 
378692ea5SArtem Dergachev // expected-no-diagnostics
478692ea5SArtem Dergachev 
578692ea5SArtem Dergachev bool a();
678692ea5SArtem Dergachev bool b();
778692ea5SArtem Dergachev 
878692ea5SArtem Dergachev // Calls method a with some extra code to pass the minimum complexity
foo1(int x)978692ea5SArtem Dergachev bool foo1(int x) {
1078692ea5SArtem Dergachev   if (x > 0)
1178692ea5SArtem Dergachev     return false;
1278692ea5SArtem Dergachev   else if (x < 0)
1378692ea5SArtem Dergachev     return a();
1478692ea5SArtem Dergachev   return true;
1578692ea5SArtem Dergachev }
1678692ea5SArtem Dergachev 
1778692ea5SArtem Dergachev // Calls method b with some extra code to pass the minimum complexity
foo2(int x)1878692ea5SArtem Dergachev bool foo2(int x) {
1978692ea5SArtem Dergachev   if (x > 0)
2078692ea5SArtem Dergachev     return false;
2178692ea5SArtem Dergachev   else if (x < 0)
2278692ea5SArtem Dergachev     return b();
2378692ea5SArtem Dergachev   return true;
2478692ea5SArtem Dergachev }
25cad15149SArtem Dergachev 
26cad15149SArtem Dergachev // Test that we don't crash on function pointer calls
27cad15149SArtem Dergachev 
28cad15149SArtem Dergachev bool (*funcPtr)(int);
29cad15149SArtem Dergachev 
fooPtr1(int x)30cad15149SArtem Dergachev bool fooPtr1(int x) {
31cad15149SArtem Dergachev   if (x > 0)
32cad15149SArtem Dergachev     return false;
33cad15149SArtem Dergachev   else if (x < 0)
34cad15149SArtem Dergachev     return funcPtr(1);
35cad15149SArtem Dergachev   return true;
36cad15149SArtem Dergachev }
3751838888SArtem Dergachev 
3851838888SArtem Dergachev // Test that we respect the template arguments of function templates
3951838888SArtem Dergachev 
4051838888SArtem Dergachev template<typename T, unsigned N>
templateFunc()4151838888SArtem Dergachev bool templateFunc() { unsigned i = N; return false; }
4251838888SArtem Dergachev 
fooTemplate1(int x)4351838888SArtem Dergachev bool fooTemplate1(int x) {
4451838888SArtem Dergachev   if (x > 0)
4551838888SArtem Dergachev     return false;
4651838888SArtem Dergachev   else if (x < 0)
4751838888SArtem Dergachev     return templateFunc<int, 1>();
4851838888SArtem Dergachev   return true;
4951838888SArtem Dergachev }
5051838888SArtem Dergachev 
fooTemplate2(int x)5151838888SArtem Dergachev bool fooTemplate2(int x) {
5251838888SArtem Dergachev   if (x > 0)
5351838888SArtem Dergachev     return false;
5451838888SArtem Dergachev   else if (x < 0)
5551838888SArtem Dergachev     return templateFunc<long, 1>();
5651838888SArtem Dergachev   return true;
5751838888SArtem Dergachev }
5851838888SArtem Dergachev 
fooTemplate3(int x)5951838888SArtem Dergachev bool fooTemplate3(int x) {
6051838888SArtem Dergachev   if (x > 0)
6151838888SArtem Dergachev     return false;
6251838888SArtem Dergachev   else if (x < 0)
6351838888SArtem Dergachev     return templateFunc<long, 2>();
6451838888SArtem Dergachev   return true;
6551838888SArtem Dergachev }
6651838888SArtem Dergachev 
6751838888SArtem Dergachev // Test that we don't just concatenate the template arguments into a string
6851838888SArtem Dergachev // without having any padding between them (e.g. foo<X, XX>() != foo<XX, X>()).
6951838888SArtem Dergachev 
7051838888SArtem Dergachev class X {};
7151838888SArtem Dergachev class XX {};
7251838888SArtem Dergachev 
7351838888SArtem Dergachev template<typename T1, typename T2>
templatePaddingFunc()7451838888SArtem Dergachev bool templatePaddingFunc() { return false; }
7551838888SArtem Dergachev 
fooTemplatePadding1(int x)7651838888SArtem Dergachev bool fooTemplatePadding1(int x) {
7751838888SArtem Dergachev   if (x > 0)
7851838888SArtem Dergachev     return false;
7951838888SArtem Dergachev   else if (x < 0)
8051838888SArtem Dergachev     return templatePaddingFunc<X, XX>();
8151838888SArtem Dergachev   return true;
8251838888SArtem Dergachev }
8351838888SArtem Dergachev 
fooTemplatePadding2(int x)8451838888SArtem Dergachev bool fooTemplatePadding2(int x) {
8551838888SArtem Dergachev   if (x > 0)
8651838888SArtem Dergachev     return false;
8751838888SArtem Dergachev   else if (x < 0)
8851838888SArtem Dergachev     return templatePaddingFunc<XX, X>();
8951838888SArtem Dergachev   return true;
9051838888SArtem Dergachev }
915f94b089SArtem Dergachev 
925f94b089SArtem Dergachev // Test that we don't crash on member functions of template instantiations.
935f94b089SArtem Dergachev 
945f94b089SArtem Dergachev template<typename T>
955f94b089SArtem Dergachev struct A {
fooA965f94b089SArtem Dergachev   void foo(T t) {}
975f94b089SArtem Dergachev };
985f94b089SArtem Dergachev 
fooTestInstantiation()995f94b089SArtem Dergachev void fooTestInstantiation() {
1005f94b089SArtem Dergachev   A<int> a;
1015f94b089SArtem Dergachev   a.foo(1);
1025f94b089SArtem Dergachev }
103