diff options
author | Sergio Martins <smartins@kde.org> | 2021-10-26 20:42:11 +0100 |
---|---|---|
committer | Sergio Martins <smartins@kde.org> | 2021-10-26 20:44:45 +0100 |
commit | 854f3408dfc9d2d96d2a9bda46660e2074315d6c (patch) | |
tree | 7b35bc05662a2f1cb5d3fee923e63354d5e52051 | |
parent | 2ea87181a3ac51e8d0c9d46ac348a8ba9a5a335c (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.cpp | 7 | ||||
-rw-r--r-- | tests/rule-of-two-soft/bug443343.cpp | 30 | ||||
-rw-r--r-- | tests/rule-of-two-soft/bug443343.cpp.expected | 1 | ||||
-rw-r--r-- | tests/rule-of-two-soft/config.json | 3 |
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" } ] } |