Author: xiangzhai Date: Sun Jun 18 20:55:50 2017 New Revision: 305659 URL: http://llvm.org/viewvc/llvm-project?rev=305659&view=rev Log: [analyzer] Teach CloneDetection about Qt Meta-Object Compiler
Reviewers: v.g.vassilev, zaks.anna, NoQ, teemperor Reviewed By: v.g.vassilev, zaks.anna, NoQ, teemperor Differential Revision: https://reviews.llvm.org/D31320 Added: cfe/trunk/test/Analysis/copypaste/autogenerated_automoc.cpp cfe/trunk/test/Analysis/copypaste/dbus_autogenerated.cpp cfe/trunk/test/Analysis/copypaste/moc_autogenerated.cpp cfe/trunk/test/Analysis/copypaste/not-autogenerated.cpp cfe/trunk/test/Analysis/copypaste/ui_autogenerated.cpp Modified: cfe/trunk/include/clang/Analysis/CloneDetection.h cfe/trunk/lib/Analysis/CloneDetection.cpp cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp Modified: cfe/trunk/include/clang/Analysis/CloneDetection.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CloneDetection.h?rev=305659&r1=305658&r2=305659&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/CloneDetection.h (original) +++ cfe/trunk/include/clang/Analysis/CloneDetection.h Sun Jun 18 20:55:50 2017 @@ -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 { Modified: cfe/trunk/lib/Analysis/CloneDetection.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CloneDetection.cpp?rev=305659&r1=305658&r2=305659&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CloneDetection.cpp (original) +++ cfe/trunk/lib/Analysis/CloneDetection.cpp Sun Jun 18 20:55:50 2017 @@ -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::constra } } +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; Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp?rev=305659&r1=305658&r2=305659&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp Sun Jun 18 20:55:50 2017 @@ -73,12 +73,17 @@ void CloneChecker::checkEndOfTranslation 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()); Added: cfe/trunk/test/Analysis/copypaste/autogenerated_automoc.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/autogenerated_automoc.cpp?rev=305659&view=auto ============================================================================== --- cfe/trunk/test/Analysis/copypaste/autogenerated_automoc.cpp (added) +++ cfe/trunk/test/Analysis/copypaste/autogenerated_automoc.cpp Sun Jun 18 20:55:50 2017 @@ -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; + } +} Added: cfe/trunk/test/Analysis/copypaste/dbus_autogenerated.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/dbus_autogenerated.cpp?rev=305659&view=auto ============================================================================== --- cfe/trunk/test/Analysis/copypaste/dbus_autogenerated.cpp (added) +++ cfe/trunk/test/Analysis/copypaste/dbus_autogenerated.cpp Sun Jun 18 20:55:50 2017 @@ -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; + } +} Added: cfe/trunk/test/Analysis/copypaste/moc_autogenerated.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/moc_autogenerated.cpp?rev=305659&view=auto ============================================================================== --- cfe/trunk/test/Analysis/copypaste/moc_autogenerated.cpp (added) +++ cfe/trunk/test/Analysis/copypaste/moc_autogenerated.cpp Sun Jun 18 20:55:50 2017 @@ -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; + } +} Added: cfe/trunk/test/Analysis/copypaste/not-autogenerated.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/not-autogenerated.cpp?rev=305659&view=auto ============================================================================== --- cfe/trunk/test/Analysis/copypaste/not-autogenerated.cpp (added) +++ cfe/trunk/test/Analysis/copypaste/not-autogenerated.cpp Sun Jun 18 20:55:50 2017 @@ -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; + } +} Added: cfe/trunk/test/Analysis/copypaste/ui_autogenerated.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/ui_autogenerated.cpp?rev=305659&view=auto ============================================================================== --- cfe/trunk/test/Analysis/copypaste/ui_autogenerated.cpp (added) +++ cfe/trunk/test/Analysis/copypaste/ui_autogenerated.cpp Sun Jun 18 20:55:50 2017 @@ -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; + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits