Closed
Bug 1208814
Opened 8 years ago
Closed 8 years ago
Prevent the default copy constructor of refcounted objects to be used
Categories
(Developer Infrastructure :: Source Code Analysis, defect)
Developer Infrastructure
Source Code Analysis
Tracking
(firefox44 fixed)
RESOLVED
FIXED
mozilla44
Tracking | Status | |
---|---|---|
firefox44 | --- | fixed |
People
(Reporter: ehsan.akhgari, Assigned: nika)
Details
Attachments
(2 files, 2 obsolete files)
3.08 KB,
patch
|
mak
:
review+
|
Details | Diff | Splinter Review |
Part 1: Add an analysis to prevent default copy constructors from being called on refcounted objects
7.20 KB,
patch
|
Details | Diff | Splinter Review |
Consider this code: class RandomRefCountedClass : public nsISupports { NS_DECL_ISUPPORTS already_AddRefed<RandomRefCountedClass> Clone() { nsRefPtr<RandomRefCountedClass> copy = new RandomRefCountedClass(*this); return copy.forget(); } nsCOMPtr<nsIFoo> mFoo; // ... }; Here we are using the default constructor of the object thinking that we're only copying mFoo and that's fine, but we have a hidden mRefCnt in the macro NS_DECL_ISUPPORTS that we'd copy as well, as a result, the refcount of the object is out of balance, and in this case we probably leak the cloned object. We should prevent this general pattern. This is actual code that I wrote. We can do that by looking for default copy constructors that are called for a refcounted object.
Assignee | ||
Comment 1•8 years ago
|
||
Do we require that a copy constructor always be explicitly deleted or implemented, or do you want to only prevent calls to the default copy constructor?
Reporter | ||
Comment 2•8 years ago
|
||
(In reply to Michael Layzell [:mystor] from comment #1) > Do we require that a copy constructor always be explicitly deleted or > implemented, or do you want to only prevent calls to the default copy > constructor? I think requiring the copy ctor being explicitly deleted is a pain since that means that you need even more boiler plate code for all refcounted objects. Let's just prevent calls to the default copy ctor.
Assignee | ||
Comment 3•8 years ago
|
||
(In reply to Ehsan Akhgari (don't ask for review please) from comment #2) > (In reply to Michael Layzell [:mystor] from comment #1) > > Do we require that a copy constructor always be explicitly deleted or > > implemented, or do you want to only prevent calls to the default copy > > constructor? > > I think requiring the copy ctor being explicitly deleted is a pain since > that means that you need even more boiler plate code for all refcounted > objects. Let's just prevent calls to the default copy ctor. Should we also prevents calls to the default assignment operator= to prevent code like: nsRefPtr<Foo> f1 = ...; nsRefPtr<Foo> f2 = ...; *f2 = *f1; Because that is also wrong (although probably much less likely to occur).
Assignee | ||
Updated•8 years ago
|
Assignee: nobody → michael
Assignee | ||
Comment 4•8 years ago
|
||
I require that refcounted objects have an mRefCnt member in this patch to be considered refcounted.
Attachment #8667362 -
Flags: review?(ehsan)
Assignee | ||
Comment 5•8 years ago
|
||
I'm not sure if you're the best person to review this change - you can forward it to someone else if someone else would be more appropriate.
Attachment #8667365 -
Flags: review?(ehsan)
Reporter | ||
Comment 6•8 years ago
|
||
(In reply to Michael Layzell [:mystor] from comment #3) > (In reply to Ehsan Akhgari (don't ask for review please) from comment #2) > > (In reply to Michael Layzell [:mystor] from comment #1) > > > Do we require that a copy constructor always be explicitly deleted or > > > implemented, or do you want to only prevent calls to the default copy > > > constructor? > > > > I think requiring the copy ctor being explicitly deleted is a pain since > > that means that you need even more boiler plate code for all refcounted > > objects. Let's just prevent calls to the default copy ctor. > > Should we also prevents calls to the default assignment operator= to prevent > code like: > > nsRefPtr<Foo> f1 = ...; > nsRefPtr<Foo> f2 = ...; > *f2 = *f1; > > Because that is also wrong (although probably much less likely to occur). Yes, in a separate bug!
Reporter | ||
Comment 7•8 years ago
|
||
Comment on attachment 8667362 [details] [diff] [review] Part 1: Add an analysis to prevent default copy constructors from being called on refcounted objects Review of attachment 8667362 [details] [diff] [review]: ----------------------------------------------------------------- ::: build/clang-plugin/clang-plugin.cpp @@ +1412,5 @@ > + DiagnosticIDs::Error, "Invalid use of compiler-provided copy constructor " > + "on refcounted type"); > + unsigned NoteID = Diag.getDiagnosticIDs()->getCustomDiagID( > + DiagnosticIDs::Note, "This constructor will incorrectly copy the mRefCnt " > + "property, and leak memory"); Can you please add "Please provide your own copy constructor which only copies the fields that need to be copied." to the note? Also I think it would be better to replace "and leak memory" with "and cause reference count imbalance issues". ::: build/clang-plugin/tests/TestRefCountedCopyConstructor.cpp @@ +16,5 @@ > + int mRefCnt; > +}; > + > +// Implicit copy constructor which is used > +class RC3 { Hmm, why do you have RC3? I think you can drop it and just use RC1.
Attachment #8667362 -
Flags: review?(ehsan) → review+
Reporter | ||
Comment 8•8 years ago
|
||
Comment on attachment 8667365 [details] [diff] [review] Part 2: Don't use the default copy constructor in nsNavHistoryQuery::Clone() Review of attachment 8667365 [details] [diff] [review]: ----------------------------------------------------------------- ::: toolkit/components/places/nsNavHistoryQuery.cpp @@ -1325,3 @@ > NS_ENSURE_TRUE(clone, NS_ERROR_OUT_OF_MEMORY); > > - clone->mRefCnt = 0; // the clone doesn't inherit our refcount Ouch!
Attachment #8667365 -
Flags: review?(ehsan) → review?(mak77)
Assignee | ||
Comment 9•8 years ago
|
||
(In reply to Ehsan Akhgari (don't ask for review please) from comment #7) > Comment on attachment 8667362 [details] [diff] [review] > Part 1: Add an analysis to prevent default copy constructors from being > called on refcounted objects > > Review of attachment 8667362 [details] [diff] [review]: > ----------------------------------------------------------------- > > ::: build/clang-plugin/clang-plugin.cpp > @@ +1412,5 @@ > > + DiagnosticIDs::Error, "Invalid use of compiler-provided copy constructor " > > + "on refcounted type"); > > + unsigned NoteID = Diag.getDiagnosticIDs()->getCustomDiagID( > > + DiagnosticIDs::Note, "This constructor will incorrectly copy the mRefCnt " > > + "property, and leak memory"); > > Can you please add "Please provide your own copy constructor which only > copies the fields that need to be copied." to the note? Also I think it > would be better to replace "and leak memory" with "and cause reference count > imbalance issues". Yup, that's a much nicer error message :) > ::: build/clang-plugin/tests/TestRefCountedCopyConstructor.cpp > @@ +16,5 @@ > > + int mRefCnt; > > +}; > > + > > +// Implicit copy constructor which is used > > +class RC3 { > > Hmm, why do you have RC3? I think you can drop it and just use RC1. Umm... Good question. I think originally I thought I might need them to be separate (I wrote the tests before I wrote the patch), but in the end I didn't.
Assignee | ||
Comment 10•8 years ago
|
||
try: https://treeherder.mozilla.org/#/jobs?repo=try&revision=53934ef52666
Attachment #8667362 -
Attachment is obsolete: true
Assignee | ||
Comment 11•8 years ago
|
||
oops - fixed the test to actually represent the change in note message
Attachment #8667393 -
Attachment is obsolete: true
Comment 12•8 years ago
|
||
Comment on attachment 8667365 [details] [diff] [review] Part 2: Don't use the default copy constructor in nsNavHistoryQuery::Clone() Review of attachment 8667365 [details] [diff] [review]: ----------------------------------------------------------------- good ol' code
Attachment #8667365 -
Flags: review?(mak77) → review+
Comment 13•8 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/afec4036eb61 https://hg.mozilla.org/integration/mozilla-inbound/rev/b80a3b03babb
Comment 14•8 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/afec4036eb61 https://hg.mozilla.org/mozilla-central/rev/b80a3b03babb
Status: NEW → RESOLVED
Closed: 8 years ago
status-firefox44:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla44
Updated•6 years ago
|
Product: Core → Firefox Build System
Updated•1 year ago
|
Product: Firefox Build System → Developer Infrastructure
You need to log in
before you can comment on or make changes to this bug.
Description
•