[cfe-commits] r169535 - /cfe/trunk/include/clang/Basic/PartialDiagnostic.h
Howard Hinnant
hhinnant at apple.com
Thu Dec 6 12:06:35 PST 2012
On Dec 6, 2012, at 2:54 PM, Matthieu Monrocq <matthieu.monrocq at gmail.com> wrote:
>
>
> On Thu, Dec 6, 2012 at 8:18 PM, Jordan Rose <jordan_rose at apple.com> wrote:
> Nice!
>
> On Dec 6, 2012, at 11:09 , Benjamin Kramer <benny.kra at googlemail.com> wrote:
>
> > Author: d0k
> > Date: Thu Dec 6 13:09:30 2012
> > New Revision: 169535
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=169535&view=rev
> > Log:
> > Add move semantics to PartialDiagnostic, which can be very expensive to copy.
> >
> > Modified:
> > cfe/trunk/include/clang/Basic/PartialDiagnostic.h
> >
> > Modified: cfe/trunk/include/clang/Basic/PartialDiagnostic.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/PartialDiagnostic.h?rev=169535&r1=169534&r2=169535&view=diff
> > ==============================================================================
> > --- cfe/trunk/include/clang/Basic/PartialDiagnostic.h (original)
> > +++ cfe/trunk/include/clang/Basic/PartialDiagnostic.h Thu Dec 6 13:09:30 2012
> > @@ -19,6 +19,7 @@
> > #include "clang/Basic/Diagnostic.h"
> > #include "clang/Basic/SourceLocation.h"
> > #include "llvm/ADT/STLExtras.h"
> > +#include "llvm/Support/Compiler.h"
> > #include "llvm/Support/DataTypes.h"
> > #include <cassert>
> >
> > @@ -200,6 +201,14 @@
> > }
> > }
> >
> > +#if LLVM_HAS_RVALUE_REFERENCES
> > + PartialDiagnostic(PartialDiagnostic &&Other)
> > + : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
> > + Allocator(Other.Allocator) {
> > + Other.DiagStorage = 0;
> > + }
> > +#endif
> > +
> > PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
> > : DiagID(Other.DiagID), DiagStorage(DiagStorage),
> > Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
> > @@ -242,6 +251,23 @@
> > return *this;
> > }
> >
> > +#if LLVM_HAS_RVALUE_REFERENCES
> > + PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
> > + if (this != &Other) {
>
> Is this really necessary? If this is true, I think the move contract has been violated anyway.
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> There was a discussion on stack overflow recently about this, and Howard chimed in: it is unnecessary.
>
> On the other hand, a `assert(this != &Other && "Illegal attempt to move toward itself")` may make sense since this can quickly become a gotcha.
My position on this issue has shifted slightly over the past year.
Self-move-assignment should not cause a crash, unless you're specifically trying to find places where self-move-assignment happens by putting an assert in. One place that self-move-assignment can happen is with self-swap. Personally I consider self-swap a performance bug. However there is nothing illegal about it.
Strictly speaking self-move-assignment is legal and should not crash. However, unlike copy assignment, there is absolutely no need for self-move-assignment to be a no-op. If self-move-assignment changes an object from a valid-not-moved-from state, to a valid-moved-from state, that is perfectly fine.
Typically the only place self-move-assignment happens, which is inside of self-swap, the operation happens on a moved-from state, and is often a no-op, as I suspect it would be just glancing at PartialDiagnostic.
In summary, my advice on the subject is to not check for self-move-assignment, but do ensure the algorithm won't crash if you do. Not crashing (not placing the object in an invalid state) is all self-move-assignment need do if you want to be C++11 conforming.
Otoh, if you want to monitor, catch, and weed out self-swaps or other accidental self-move-assignments, putting an assert in there is the best way to do that.
Howard
More information about the cfe-commits
mailing list