aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergio Martins <smartins@kde.org>2021-10-26 20:42:11 +0100
committerSergio Martins <smartins@kde.org>2021-10-26 20:44:45 +0100
commit854f3408dfc9d2d96d2a9bda46660e2074315d6c (patch)
tree7b35bc05662a2f1cb5d3fee923e63354d5e52051
parent2ea87181a3ac51e8d0c9d46ac348a8ba9a5a335c (diff)
rule-of-two-soft: Honour explicitly defaulted copy-ctor/operator
The user signaled he knows what he's doing and there's even valid use cases BUG: 443343
-rw-r--r--src/checks/level1/rule-of-two-soft.cpp7
-rw-r--r--tests/rule-of-two-soft/bug443343.cpp30
-rw-r--r--tests/rule-of-two-soft/bug443343.cpp.expected1
-rw-r--r--tests/rule-of-two-soft/config.json3
4 files changed, 39 insertions, 2 deletions
diff --git a/src/checks/level1/rule-of-two-soft.cpp b/src/checks/level1/rule-of-two-soft.cpp
index 71d5d7e0..451eacf8 100644
--- a/src/checks/level1/rule-of-two-soft.cpp
+++ b/src/checks/level1/rule-of-two-soft.cpp
@@ -48,7 +48,9 @@ void RuleOfTwoSoft::VisitStmt(Stmt *s)
if (method && method->getParent() && method->isCopyAssignmentOperator()) {
CXXRecordDecl *record = method->getParent();
const bool hasCopyCtor = record->hasNonTrivialCopyConstructor();
- const bool hasCopyAssignOp = record->hasNonTrivialCopyAssignment();
+ const bool hasCopyAssignOp = record->hasNonTrivialCopyAssignment()
+ || method->isExplicitlyDefaulted();
+
if (hasCopyCtor && !hasCopyAssignOp && !isBlacklisted(record)) {
string msg = "Using assign operator but class " + record->getQualifiedNameAsString() + " has copy-ctor but no assign operator";
emitWarning(clazy::getLocStart(s), msg);
@@ -58,7 +60,8 @@ void RuleOfTwoSoft::VisitStmt(Stmt *s)
CXXConstructorDecl *ctorDecl = ctorExpr->getConstructor();
CXXRecordDecl *record = ctorDecl->getParent();
if (ctorDecl->isCopyConstructor() && record) {
- const bool hasCopyCtor = record->hasNonTrivialCopyConstructor();
+ const bool hasCopyCtor = record->hasNonTrivialCopyConstructor()
+ || ctorDecl->isExplicitlyDefaulted();
const bool hasCopyAssignOp = record->hasNonTrivialCopyAssignment();
if (!hasCopyCtor && hasCopyAssignOp && !isBlacklisted(record)) {
string msg = "Using copy-ctor but class " + record->getQualifiedNameAsString() + " has a trivial copy-ctor but non trivial assign operator";
diff --git a/tests/rule-of-two-soft/bug443343.cpp b/tests/rule-of-two-soft/bug443343.cpp
new file mode 100644
index 00000000..82c52eba
--- /dev/null
+++ b/tests/rule-of-two-soft/bug443343.cpp
@@ -0,0 +1,30 @@
+struct Test
+{
+ Test() {}
+ ~Test() { }
+
+ Test(const Test &) {}
+ Test& operator=(const Test&) = default;
+};
+
+void test()
+{
+ Test t;
+ Test t2;
+ t = t2; // OK, the developer explicitly says he wants the default copy-assign op
+}
+
+struct Test2
+{
+ Test2() {}
+ ~Test2() { }
+
+ Test2(const Test2 &) {}
+};
+
+void test2()
+{
+ Test2 t;
+ Test2 t2;
+ t = t2; // Warn
+}
diff --git a/tests/rule-of-two-soft/bug443343.cpp.expected b/tests/rule-of-two-soft/bug443343.cpp.expected
new file mode 100644
index 00000000..5be6cf37
--- /dev/null
+++ b/tests/rule-of-two-soft/bug443343.cpp.expected
@@ -0,0 +1 @@
+rule-of-two-soft/bug443343.cpp:29:5: warning: Using assign operator but class Test2 has copy-ctor but no assign operator [-Wclazy-rule-of-two-soft]
diff --git a/tests/rule-of-two-soft/config.json b/tests/rule-of-two-soft/config.json
index f26a95af..2432ba66 100644
--- a/tests/rule-of-two-soft/config.json
+++ b/tests/rule-of-two-soft/config.json
@@ -5,6 +5,9 @@
},
{
"filename" : "bug375537.cpp"
+ },
+ {
+ "filename" : "bug443343.cpp"
}
]
}