Index: include/clang/Analysis/CloneDetection.h =================================================================== --- include/clang/Analysis/CloneDetection.h +++ include/clang/Analysis/CloneDetection.h @@ -319,6 +319,17 @@ void constrain(std::vector &Result); }; +struct AutoGeneratedCloneConstraint { + bool isAutoGenerated(const CloneDetector::CloneGroup &Group); + + void constrain(std::vector &CloneGroups) { + CloneConstraint::filterGroups( + CloneGroups, [this](const CloneDetector::CloneGroup &Group) { + return isAutoGenerated(Group); + }); + } +}; + /// Analyzes the pattern of the referenced variables in a statement. class VariablePattern { Index: lib/Analysis/CloneDetection.cpp =================================================================== --- lib/Analysis/CloneDetection.cpp +++ lib/Analysis/CloneDetection.cpp @@ -366,6 +366,24 @@ } } +bool AutoGeneratedCloneConstraint::isAutoGenerated(const CloneDetector::CloneGroup &Group) { + if (Group.empty()) + return false; + + for (const StmtSequence &S : Group) { + const Decl *D = S.getContainingDecl(); + const SourceManager &SM = D->getASTContext().getSourceManager(); + StringRef Filename = SM.getFilename(D->getLocation()); + if (Filename.find(StringRef("moc_")) != StringRef::npos || + Filename.find(StringRef("_automoc.")) != StringRef::npos || + Filename.find(StringRef(".moc")) != StringRef::npos) { + return true; + } + } + + return false; +} + static size_t createHash(llvm::MD5 &Hash) { size_t HashCode; Index: lib/StaticAnalyzer/Checkers/CloneChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -78,7 +78,8 @@ // because reportSuspiciousClones() wants to search them for errors. std::vector AllCloneGroups; - Detector.findClones(AllCloneGroups, RecursiveCloneTypeIIConstraint(), + Detector.findClones(AllCloneGroups, AutoGeneratedCloneConstraint(), + RecursiveCloneTypeIIConstraint(), MinComplexityConstraint(MinComplexity), MinGroupSizeConstraint(2), OnlyLargestCloneConstraint()); Index: test/Analysis/copypaste/k3blib_automoc.cpp =================================================================== --- test/Analysis/copypaste/k3blib_automoc.cpp +++ test/Analysis/copypaste/k3blib_automoc.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s + +// expected-no-diagnostics + +/* This file is autogenerated, do not edit*/ + +// clang -E RealMetaObjectCompiler_automoc.cpp > ~/PreprocessedMOC_automoc.cpp + +void f1() { + int *p1 = new int[1]; + int *p2 = new int[1]; + if (p1) { + delete [] p1; + p1 = nullptr; + } + // Copy-paste above block but careless forget to change something + if (p2) { + delete [] p1; // no-warning + p2 = nullptr; + } +} Index: test/Analysis/copypaste/moc_k3bactivepipe.cpp =================================================================== --- test/Analysis/copypaste/moc_k3bactivepipe.cpp +++ test/Analysis/copypaste/moc_k3bactivepipe.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s + +// expected-no-diagnostics + +/**************************************************************************** +** Meta object code from reading C++ file 'k3bactivepipe.h' +** +** Created by: The Qt Meta Object Compiler version 67 (Qt 5.8.0) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +// clang -E moc_RealMetaObjectCompiler.cpp > ~/moc_PreprocessedMOC.cpp + +void f1() { + int *p1 = new int[1]; + int *p2 = new int[1]; + if (p1) { + delete [] p1; + p1 = nullptr; + } + // Copy-paste above block but careless forget to change something + if (p2) { + delete [] p1; // no-warning + p2 = nullptr; + } +}