This is an archive of the discontinued LLVM Phabricator instance.

tsan: remove implicit memcpy in MutexSet::Desc::operator=()
ClosedPublic

Authored by dvyukov on Aug 12 2021, 5:52 AM.

Details

Summary

The default compiler-generated MutexSet::Desc::operator=()
now contains memcpy() call since Desc become bigger.
This fails in debug mode since we call interceptor from within the runtime.
Define own operator=() using internal_memcpy().
This also makes copy ctor necessary, otherwise:
tsan_mutexset.h:33:11: warning: definition of implicit copy constructor for
'Desc' is deprecated because it has a user-declared copy assignment operator
And if we add copy ctor, we also need the default ctor
since it's called by MutexSet ctor.

Depends on D107911.

Diff Detail

Event Timeline

dvyukov requested review of this revision.Aug 12 2021, 5:52 AM
dvyukov created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptAug 12 2021, 5:52 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
melver accepted this revision.Aug 12 2021, 5:56 AM
melver added inline comments.
compiler-rt/lib/tsan/rtl/tsan_mutexset.h
35

No need to implement, just make it emit the default:

Desc(const Desc&) = default;

I assume copy-constructor doesn't emit memcpy somehow?

This revision is now accepted and ready to land.Aug 12 2021, 5:56 AM
melver added inline comments.Aug 12 2021, 5:58 AM
compiler-rt/lib/tsan/rtl/tsan_mutexset.h
35

Hmm, of course '= default' doesn't work if it doesn't end up using operator=.
In which case, explicit implementation is needed and disregard my comment.

dvyukov updated this revision to Diff 365985.Aug 12 2021, 6:05 AM

restored MutexSet::MutexSet

This revision was landed with ongoing or failed builds.Aug 12 2021, 6:10 AM
This revision was automatically updated to reflect the committed changes.

restored MutexSet::MutexSet

W/o this compiler managed to insert memset before the call to MutexSet ctor (no ideas why would it do it, but restoring the ctor helps):

// Too large for stack.
alignas(MutexSet) static char mset_storage[sizeof(MutexSet)];
MutexSet &mset = *new (mset_storage) MutexSet();
4c0b4b:       4c 8d 35 56 b9 2e 03    lea    0x32eb956(%rip),%r14        # 37ac4a8 <_ZZN6__tsan2v312RestoreStackEjNS0_9EventTypeENS_3SidENS_5EpochEmmmPNS_17VarSizeStackTraceEPNS_8MutexSetEPmE12mset_storage>
4c0b52:       ba 10 03 00 00          mov    $0x310,%edx
4c0b57:       4c 89 f7                mov    %r14,%rdi
4c0b5a:       31 f6                   xor    %esi,%esi
4c0b5c:       e8 8f 7f f9 ff          callq  458af0 <__interceptor_memset>
4c0b61:       4c 89 f7                mov    %r14,%rdi
4c0b64:       e8 57 be fe ff          callq  4ac9c0 <_ZN6__tsan8MutexSetC2Ev>
compiler-rt/lib/tsan/rtl/tsan_mutexset.h
35

Yes, I think the compiler can happily emit memcpy into the generated copy ctor.