diff --git a/lib/Analysis/CloneDetection.cpp b/lib/Analysis/CloneDetection.cpp
index a26409f950f46eae037de2c62a7566d9f946f07c..ee1c6943f28923764478b9e17848ed833cd23089 100644
--- a/lib/Analysis/CloneDetection.cpp
+++ b/lib/Analysis/CloneDetection.cpp
@@ -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 ---------------------------------------------------------//
diff --git a/test/Analysis/copypaste/call.cpp b/test/Analysis/copypaste/call.cpp
index 0c10262a31df74c8afda32b4bbc1fbe0ff65f3ae..46df02280ee1e19e55cb71e4aa76741d967395d7 100644
--- a/test/Analysis/copypaste/call.cpp
+++ b/test/Analysis/copypaste/call.cpp
@@ -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;
+}