diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index 3b8173558408114283f037265ed3fcecf1e9a55a..3398a1f40af5b3ca939ad96b54dd6f5489f0a771 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -17,6 +17,8 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Regex.h"
 #include <vector>
 
 namespace clang {
@@ -319,6 +321,26 @@ struct OnlyLargestCloneConstraint {
   void constrain(std::vector<CloneDetector::CloneGroup> &Result);
 };
 
+struct AutoGeneratedCloneConstraint {
+  StringRef IgnoredFilesPattern;
+  std::shared_ptr<llvm::Regex> IgnoredFilesRegex;
+
+  AutoGeneratedCloneConstraint(StringRef IgnoredFilesPattern) 
+      : IgnoredFilesPattern(IgnoredFilesPattern) {
+    IgnoredFilesRegex = std::make_shared<llvm::Regex>("^(" +
+        IgnoredFilesPattern.str() + "$)");
+  }
+
+  bool isAutoGenerated(const CloneDetector::CloneGroup &Group);
+
+  void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
+    CloneConstraint::filterGroups(
+        CloneGroups, [this](const CloneDetector::CloneGroup &Group) {
+          return isAutoGenerated(Group);
+        });
+  }
+};
+
 /// Analyzes the pattern of the referenced variables in a statement.
 class VariablePattern {
 
diff --git a/lib/Analysis/CloneDetection.cpp b/lib/Analysis/CloneDetection.cpp
index 5bbcbe4e5722b44ee630a9e3a3d278e58b3443c2..3b44fab9d74ad4972b8f09bdb8376218717a8703 100644
--- a/lib/Analysis/CloneDetection.cpp
+++ b/lib/Analysis/CloneDetection.cpp
@@ -18,9 +18,9 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Path.h"
 
 using namespace clang;
 
@@ -366,6 +366,23 @@ void OnlyLargestCloneConstraint::constrain(
   }
 }
 
+bool AutoGeneratedCloneConstraint::isAutoGenerated(const CloneDetector::CloneGroup &Group) {
+  std::string Error;
+  if (IgnoredFilesPattern.empty() || Group.empty() || 
+      !IgnoredFilesRegex->isValid(Error))
+    return false;
+
+  for (const StmtSequence &S : Group) {
+    const SourceManager &SM = S.getASTContext().getSourceManager();
+    StringRef Filename = llvm::sys::path::filename(SM.getFilename(
+        S.getContainingDecl()->getLocation()));
+    if (IgnoredFilesRegex->match(Filename))
+      return true;
+  }
+
+  return false;
+}
+
 static size_t createHash(llvm::MD5 &Hash) {
   size_t HashCode;
 
diff --git a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
index 1885b0e39203c44d2945f33ddf15548f0ee7a72f..d0898adf49fb633f1b466d5c9ad6810b84d0758f 100644
--- a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
@@ -73,12 +73,17 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
   bool ReportNormalClones = Mgr.getAnalyzerOptions().getBooleanOption(
       "ReportNormalClones", true, this);
 
+  StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions().getOptionAsString(
+      "IgnoredFilesPattern", "", this);
+
   // Let the CloneDetector create a list of clones from all the analyzed
   // statements. We don't filter for matching variable patterns at this point
   // because reportSuspiciousClones() wants to search them for errors.
   std::vector<CloneDetector::CloneGroup> AllCloneGroups;
 
-  Detector.findClones(AllCloneGroups, RecursiveCloneTypeIIConstraint(),
+  Detector.findClones(AllCloneGroups,
+                      AutoGeneratedCloneConstraint(IgnoredFilesPattern),
+                      RecursiveCloneTypeIIConstraint(),
                       MinComplexityConstraint(MinComplexity),
                       MinGroupSizeConstraint(2), OnlyLargestCloneConstraint());
 
diff --git a/test/Analysis/copypaste/autogenerated_automoc.cpp b/test/Analysis/copypaste/autogenerated_automoc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55963c4545c9a3865495f89e3f2d40570c1812fb
--- /dev/null
+++ b/test/Analysis/copypaste/autogenerated_automoc.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|.*_automoc.cpp" -verify %s
+
+// Because files that have `_automoc.' in their names are most likely autogenerated,
+// we suppress copy-paste warnings here.
+
+// expected-no-diagnostics
+
+void f1() {
+  int *p1 = new int[1];
+  int *p2 = new int[1];
+  if (p1) {
+    delete [] p1;
+    p1 = nullptr;
+  }
+  if (p2) {
+    delete [] p1; // no-warning
+    p2 = nullptr;
+  }
+}
diff --git a/test/Analysis/copypaste/dbus_autogenerated.cpp b/test/Analysis/copypaste/dbus_autogenerated.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1824375658130bfaf4aeded299e7833b4320fa7b
--- /dev/null
+++ b/test/Analysis/copypaste/dbus_autogenerated.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|dbus_|.*_automoc" -verify %s
+
+// Because files that have `dbus_' in their names are most likely autogenerated,
+// we suppress copy-paste warnings here.
+
+// expected-no-diagnostics
+
+void f1() {
+  int *p1 = new int[1];
+  int *p2 = new int[1];
+  if (p1) {
+    delete [] p1;
+    p1 = nullptr;
+  }
+  if (p2) {
+    delete [] p1; // no-warning
+    p2 = nullptr;
+  }
+}
diff --git a/test/Analysis/copypaste/moc_autogenerated.cpp b/test/Analysis/copypaste/moc_autogenerated.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..626fe2a3dd0703e9166a69399ab1b6d1f80fcf9c
--- /dev/null
+++ b/test/Analysis/copypaste/moc_autogenerated.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|.*_automoc" -verify %s
+
+// Because files that have `moc_' in their names are most likely autogenerated,
+// we suppress copy-paste warnings here.
+
+// expected-no-diagnostics
+
+void f1() {
+  int *p1 = new int[1];
+  int *p2 = new int[1];
+  if (p1) {
+    delete [] p1;
+    p1 = nullptr;
+  }
+  if (p2) {
+    delete [] p1; // no-warning
+    p2 = nullptr;
+  }
+}
diff --git a/test/Analysis/copypaste/not-autogenerated.cpp b/test/Analysis/copypaste/not-autogenerated.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..765e7aaf2aab6970e93e218e855712afba738ed7
--- /dev/null
+++ b/test/Analysis/copypaste/not-autogenerated.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|ui_|dbus_|.*_automoc" -verify %s
+
+void f1() {
+  int *p1 = new int[1];
+  int *p2 = new int[1];
+  if (p1) {
+    delete [] p1; // expected-note{{Similar code using 'p1' here}}
+    p1 = nullptr;
+  }
+  if (p2) {
+    delete [] p1; // expected-warning{{Potential copy-paste error; did you really mean to use 'p1' here?}}
+    p2 = nullptr;
+  }
+}
diff --git a/test/Analysis/copypaste/ui_autogenerated.cpp b/test/Analysis/copypaste/ui_autogenerated.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a08c33fe9e2a0e8f8b41550173ed3c49cb010217
--- /dev/null
+++ b/test/Analysis/copypaste/ui_autogenerated.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|ui_|.*_automoc" -verify %s
+
+// Because files that have `ui_' in their names are most likely autogenerated,
+// we suppress copy-paste warnings here.
+
+// expected-no-diagnostics
+
+void f1() {
+  int *p1 = new int[1];
+  int *p2 = new int[1];
+  if (p1) {
+    delete [] p1;
+    p1 = nullptr;
+  }
+  if (p2) {
+    delete [] p1; // no-warning
+    p2 = nullptr;
+  }
+}