Author: dergachev Date: Sat Aug 20 04:57:21 2016 New Revision: 279366 URL: http://llvm.org/viewvc/llvm-project?rev=279366&view=rev Log: [analyzer] Make CloneDetector consider template arguments.
For example, code samples `isa<Stmt>(S)' and `isa<Expr>(S)' are no longer considered to be clones. Patch by Raphael Isemann! Differential Revision: https://reviews.llvm.org/D23555 Modified: cfe/trunk/lib/Analysis/CloneDetection.cpp cfe/trunk/test/Analysis/copypaste/call.cpp Modified: cfe/trunk/lib/Analysis/CloneDetection.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CloneDetection.cpp?rev=279366&r1=279365&r2=279366&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CloneDetection.cpp (original) +++ cfe/trunk/lib/Analysis/CloneDetection.cpp Sat Aug 20 04:57:21 2016 @@ -315,8 +315,26 @@ public: //--- Calls --------------------------------------------------------------// DEF_ADD_DATA(CallExpr, { // Function pointers don't have a callee and we just skip hashing it. - if (S->getDirectCallee()) - addData(S->getDirectCallee()->getQualifiedNameAsString()); + if (const FunctionDecl *D = S->getDirectCallee()) { + // If the function is a template instantiation, we also need to handle + // the template arguments as they are no included in the qualified name. + if (D->isTemplateInstantiation()) { + auto Args = D->getTemplateSpecializationArgs(); + std::string ArgString; + + // Print all template arguments into ArgString + llvm::raw_string_ostream OS(ArgString); + for (unsigned i = 0; i < Args->size(); ++i) { + Args->get(i).print(Context.getLangOpts(), OS); + // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'. + OS << '\n'; + } + OS.flush(); + + addData(ArgString); + } + addData(D->getQualifiedNameAsString()); + } }) //--- Exceptions ---------------------------------------------------------// Modified: cfe/trunk/test/Analysis/copypaste/call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/call.cpp?rev=279366&r1=279365&r2=279366&view=diff ============================================================================== --- cfe/trunk/test/Analysis/copypaste/call.cpp (original) +++ cfe/trunk/test/Analysis/copypaste/call.cpp Sat Aug 20 04:57:21 2016 @@ -34,3 +34,57 @@ bool fooPtr1(int x) { return funcPtr(1); return true; } + +// Test that we respect the template arguments of function templates + +template<typename T, unsigned N> +bool templateFunc() { unsigned i = N; return false; } + +bool fooTemplate1(int x) { + if (x > 0) + return false; + else if (x < 0) + return templateFunc<int, 1>(); + return true; +} + +bool fooTemplate2(int x) { + if (x > 0) + return false; + else if (x < 0) + return templateFunc<long, 1>(); + return true; +} + +bool fooTemplate3(int x) { + if (x > 0) + return false; + else if (x < 0) + return templateFunc<long, 2>(); + return true; +} + +// Test that we don't just concatenate the template arguments into a string +// without having any padding between them (e.g. foo<X, XX>() != foo<XX, X>()). + +class X {}; +class XX {}; + +template<typename T1, typename T2> +bool templatePaddingFunc() { return false; } + +bool fooTemplatePadding1(int x) { + if (x > 0) + return false; + else if (x < 0) + return templatePaddingFunc<X, XX>(); + return true; +} + +bool fooTemplatePadding2(int x) { + if (x > 0) + return false; + else if (x < 0) + return templatePaddingFunc<XX, X>(); + return true; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits