xiangzhai updated this revision to Diff 102796.
xiangzhai added a comment.
Dear Raphael,
I updated my patch as you suggested, please review it, thanks a lot!
And I noticed that you are doing Performance optimizations for the CloneChecker
https://reviews.llvm.org/D34182 I will rebase my patch if you kindly commit.
Regards,
Leslie Zhai
Repository:
rL LLVM
https://reviews.llvm.org/D31320
Files:
include/clang/Analysis/CloneDetection.h
lib/Analysis/CloneDetection.cpp
lib/StaticAnalyzer/Checkers/CloneChecker.cpp
test/Analysis/copypaste/autogenerated_automoc.cpp
test/Analysis/copypaste/dbus_autogenerated.cpp
test/Analysis/copypaste/moc_autogenerated.cpp
test/Analysis/copypaste/not-autogenerated.cpp
test/Analysis/copypaste/ui_autogenerated.cpp
Index: test/Analysis/copypaste/ui_autogenerated.cpp
===================================================================
--- test/Analysis/copypaste/ui_autogenerated.cpp
+++ 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;
+ }
+}
Index: test/Analysis/copypaste/not-autogenerated.cpp
===================================================================
--- test/Analysis/copypaste/not-autogenerated.cpp
+++ 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;
+ }
+}
Index: test/Analysis/copypaste/moc_autogenerated.cpp
===================================================================
--- test/Analysis/copypaste/moc_autogenerated.cpp
+++ 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;
+ }
+}
Index: test/Analysis/copypaste/dbus_autogenerated.cpp
===================================================================
--- test/Analysis/copypaste/dbus_autogenerated.cpp
+++ 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;
+ }
+}
Index: test/Analysis/copypaste/autogenerated_automoc.cpp
===================================================================
--- test/Analysis/copypaste/autogenerated_automoc.cpp
+++ 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;
+ }
+}
Index: lib/StaticAnalyzer/Checkers/CloneChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CloneChecker.cpp
+++ lib/StaticAnalyzer/Checkers/CloneChecker.cpp
@@ -73,12 +73,17 @@
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());
Index: lib/Analysis/CloneDetection.cpp
===================================================================
--- lib/Analysis/CloneDetection.cpp
+++ lib/Analysis/CloneDetection.cpp
@@ -18,9 +18,10 @@
#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"
+#include "llvm/Support/Regex.h"
using namespace clang;
@@ -366,6 +367,26 @@
}
}
+bool AutoGeneratedCloneConstraint::isAutoGenerated(const CloneDetector::CloneGroup &Group) {
+ if (IgnoredFilesPattern.empty() || Group.empty())
+ return false;
+
+ std::string Error;
+ llvm::Regex R(StringRef("^(" + IgnoredFilesPattern.str() + "$)"));
+ if (!R.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 (R.match(Filename))
+ return true;
+ }
+
+ return false;
+}
+
static size_t createHash(llvm::MD5 &Hash) {
size_t HashCode;
Index: include/clang/Analysis/CloneDetection.h
===================================================================
--- include/clang/Analysis/CloneDetection.h
+++ include/clang/Analysis/CloneDetection.h
@@ -17,6 +17,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <vector>
namespace clang {
@@ -319,6 +320,22 @@
void constrain(std::vector<CloneDetector::CloneGroup> &Result);
};
+struct AutoGeneratedCloneConstraint {
+ StringRef IgnoredFilesPattern;
+
+ AutoGeneratedCloneConstraint(StringRef IgnoredFilesPattern)
+ : IgnoredFilesPattern(IgnoredFilesPattern) {}
+
+ 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 {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits