This is an archive of the discontinued LLVM Phabricator instance.

[Diagnostics] Warn when class implements a copy constructor/copy assignment operator, but missing the copy assignment operator/copy constructor
AbandonedPublic

Authored by xbolva00 on Sep 28 2019, 1:15 PM.

Diff Detail

Event Timeline

xbolva00 created this revision.Sep 28 2019, 1:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 28 2019, 1:15 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
xbolva00 updated this revision to Diff 222301.Sep 28 2019, 1:16 PM

Please add test cases showing the intended behavior for

  • when the copy constructor is explicitly defaulted but the copy assignment operator is {implicitly defaulted, implicitly deleted, user-provided}
  • when the copy assignment operator is explicitly defaulted but the copy constructor is {implicitly defaulted, implicitly deleted, user-provided}
  • when the {copy constructor, copy assignment operator} is user-provided but the other is implicitly deleted

An example of an implicitly deleted copy assignment operator would be

struct A {
    int& x;
    A(const A& rhs) : x(rhs.x) {}
};

Also, how does the presence of a user-provided destructor interact with this diagnostic? If I provide a destructor but implicitly default my copy operations, isn't that just as bad, Rule-of-Three-wise?

xbolva00 added a comment.EditedSep 28 2019, 1:49 PM

if I provide a destructor but implicitly default my copy operations, isn't that just as bad, Rule-of-Three-wise?

Yeah, I am wondering about this too, whether we should check the whole Rule-of-Three. Suggestions from other reviewers?

Since https://en.cppreference.com/w/cpp/language/rule_of_three says "almost always" (note "almost") I'd say this probably belongs more in clang-tidy territory – I'm guessing false positive rate is very high for this. Can you collect some true / false positive statistics on some large open-source project (chromium, firefox, open office, …)?

Since C++11 it's rule of 0/3/5, so this should probably handle the move ctor/assign op too.

xbolva00 abandoned this revision.Sep 29 2019, 11:13 AM

Yeah, if we want to check rule of 3, clang-tidy is better choice.

+1 for clang-tidy. GCC's closest to this is -Weffc++ which limits the rule of 3 warning to only "classes that have dynamic memory allocation" (though I'm not sure exactly what conditions it uses to decide that - it doesn't warn on anything in the test cases provided in this patch, it does warn if you add a dtor to Clz that deletes buf:
rule3.cpp:1:7: warning: ‘class Clz’ has pointer data members [-Weffc++]
class Clz // expected-warning {{class implements custom copy assignment operator but missing custom copy constructor}}

^~~

rule3.cpp:1:7: warning: but does not override ‘Clz(const Clz&)’ [-Weffc++]

xbolva00 added a comment.EditedNov 12 2019, 6:47 AM

Should we reconsider this as a clang warning? I found that the newest GCC can diagnose it.

GCC 9+:

-Wdeprecated-copy, implied by -Wextra, warns about the C++11 deprecation of implicitly declared copy constructor and assignment operator if one of them is user-provided. -Wdeprecated-copy-dtor also warns if the destructor is user-provided, as specified in C++11.

It woule be nice to keep compatibility. -Wextra seems reasonable for me too.

xbolva00 reclaimed this revision.Nov 12 2019, 6:47 AM

Yeah, I'm OK with warning on the deprecated cases (especially for symmetry with GCC's warning) - not sure why that didn't occur to me/why I didn't mention it in my previous comment...

Deprecation wording is, in C++17, 15.8.1 [class.copy.ctor] p6, and 15.8.2 [class.copy.assign] p2.

Ah, Clang has it under -Wdeprecated. https://clang.llvm.org/docs/DiagnosticsReference.html#wdeprecated.

But combo -Wall -Wextra does not enable this warning, sadly.

This should be extracted to -Wdeprecated-copy and put into -Wextra. Seems fine for you?

Ah, Clang has it under -Wdeprecated. https://clang.llvm.org/docs/DiagnosticsReference.html#wdeprecated.

But combo -Wall -Wextra does not enable this warning, sadly.

This should be extracted to -Wdeprecated-copy and put into -Wextra. Seems fine for you?

Sounds plausible to me - though I'd expect @rsmith should probably have a final say before that's submitted.

Yes, i will prepare a new patch and add him as a reviewer.