// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s // expected-no-diagnostics bool a(); bool b(); // Calls method a with some extra code to pass the minimum complexity bool foo1(int x) { if (x > 0) return false; else if (x < 0) return a(); return true; } // Calls method b with some extra code to pass the minimum complexity bool foo2(int x) { if (x > 0) return false; else if (x < 0) return b(); return true; } // Test that we don't crash on function pointer calls bool (*funcPtr)(int); bool fooPtr1(int x) { if (x > 0) return false; else if (x < 0) return funcPtr(1); return true; } // Test that we respect the template arguments of function templates template bool templateFunc() { unsigned i = N; return false; } bool fooTemplate1(int x) { if (x > 0) return false; else if (x < 0) return templateFunc(); return true; } bool fooTemplate2(int x) { if (x > 0) return false; else if (x < 0) return templateFunc(); return true; } bool fooTemplate3(int x) { if (x > 0) return false; else if (x < 0) return templateFunc(); return true; } // Test that we don't just concatenate the template arguments into a string // without having any padding between them (e.g. foo() != foo()). class X {}; class XX {}; template bool templatePaddingFunc() { return false; } bool fooTemplatePadding1(int x) { if (x > 0) return false; else if (x < 0) return templatePaddingFunc(); return true; } bool fooTemplatePadding2(int x) { if (x > 0) return false; else if (x < 0) return templatePaddingFunc(); return true; } // Test that we don't crash on member functions of template instantiations. template struct A { void foo(T t) {} }; void fooTestInstantiation() { A a; a.foo(1); }